在项目中有这么一种需求

需要后台开启服务,时刻记录用户和软件的交互行为,一旦交互发生,就向服务器测发送一条消息

解决方案:

一、创建一个service服务类

在service中开启一个线程,service类具有一个记录消息队列的成员变量,在service的oncreate方法中开启一个循环,检测此队列,如果队列中存在消息即发送,并在发送之后删除此消息,代码如下:

package com.test.remotecontroller.services;

import java.util.LinkedList;
import java.util.Queue; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder; import com.google.gson.Gson;
import com.test.remotecontroller.entity.Behavior;
import com.test.remotecontroller.entity.NewBehavior;
import com.wotlab.home.moneyplantairs.web.SendRequest; public class SendBehaviorService extends Service { private MyBinder mBinder = new MyBinder();
private Queue<NewBehavior> queue = new LinkedList<NewBehavior>();
private Thread thread = null;
private boolean flag = true; private Gson gson = new Gson(); @Override
public IBinder onBind(Intent intent) {
return mBinder;
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
} @Override
public void onCreate() {
thread = new Thread(new Runnable() {
@Override
public void run() {
while (flag) {
NewBehavior item = queue.peek();
try {
if (item != null) {
item.setDefaultEmpty();
if (SendRequest.Send(gson.toJson(item)))
queue.remove(item);
else
thread.sleep(5000);
} else {
thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
thread.start();
} @Override
public void onDestroy() {
flag = false;
super.onDestroy();
} public boolean insertItem(NewBehavior item) {
return queue.offer(item);
} public class MyBinder extends Binder {
public SendBehaviorService getService() {
return SendBehaviorService.this;
}
} }

二、关于该service的启动

service的启动有两种方法,具体可以参照service的生命周期描述

(1)通过context的startService(intent)方法,这种方法的执行周期是onCreate(仅仅执行一次)——>onStartCommand(每次调用startService方法都可以执行)——>(如果手工调用stopService(intent)方法,那么——>onDestroy()方法,否则该service将一直运行)。service没有onPause,onResume等生命周期

(2)通过context的bindService(intent,conn,Service.BIND_AUTO_CREATE)方法,此时执行的生命周期是onCreate(仅仅执行一次)——>onBind()(仅仅执行一次)——>(如果调用unbindService(conn)方法,那么执行onUnbind()方法,之后自动调用onDestroy方法)。使用这种方法service可以和前台进行通信

(3)一种特殊的情况是,如果某个service之前已经由某个客户端通过startService启动了,那么之后其他客户端通过bindservice()方法调用,再调用unbind()方法,最后又嗲用了bindService()方法

那么执行的生命周期方法是

onCreate()——>onStart()——>onBind()——>onUnbind()[重写该方法 的时候返回了true]——>onRebind();

在自己的项目中,是使用bind方法使用该service(自己的疑问,gaiservice的生命周期应当是程序级别的,这样和activity绑定,其生命周期岂不是手activity生命周期影响了么?)

package com.test.remotecontroller;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast; import com.test.remotecontroler.R;
import com.test.remotecontroller.entity.Device;
import com.test.remotecontroller.entity.Sensor;
import com.test.remotecontroller.handler.DiscoverTask;
import com.test.remotecontroller.handler.ReceiveTask;
import com.test.remotecontroller.handler.SearchTask;
import com.test.remotecontroller.services.SendBehaviorService;
import com.test.remotecontroller.services.SendBehaviorService.MyBinder;
import com.wotlab.home.moneyplantairs.utils.IsWifi;
import com.wotlab.home.moneyplantairs.utils.MyDeviceListAdapter;
import com.wotlab.home.moneyplantairs.utils.TaskCallBack;
import com.wotlab.home.moneyplantairs.utils.WiFiUtils; /**
* 设备列表页面
*
* @author lx
*
*/
public class DeviceListActivity extends Activity { public static MyBinder binder = null; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_list);
bindService(new Intent(this, SendBehaviorService.class), conn,
Context.BIND_AUTO_CREATE); } private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) { } @Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MyBinder) service;
}
}; /**
@Override
protected void onDestroy() {
//不晓得为啥这里不是unbind方法
stopService(new Intent(this, SendBehaviorService.class));
super.onDestroy();
} }

android 后台运行service实现和后台的持续交互的更多相关文章

  1. 在后台运行erlang;在需要时连回交互模式

    * 1. 启动后台运行的erlang环境 按以下命令: erl -detached -name a@127.0.0.1 注意,-name的值必须是xxxx@ip的形式.其中xxxx是英文名,ip必须是 ...

  2. Android长时间后台运行Service

         项目需要在后台获取GPS经纬度.当用户对手机有一段时间没有操作后,屏幕(Screen)将从高亮(Bright)变为暗淡(Dim),如果再过段时间没操作, 屏幕(Screen)将又由暗淡(Di ...

  3. Android课程---关于Service的学习(后台运行)

    MainActivity.java package com.hanqi.test2; import android.content.ComponentName; import android.cont ...

  4. iOS7程序后台运行

    介绍 这次 iOS7 对程序后台运行进行了加强,但是仅仅是加强而已,要想像 Android 程序那样自由当然就别想了,苹果这么做主要还是出于电池使用时间考虑,但是这次的加强对大部分程序基本够用. 在介 ...

  5. IOS高级开发~开机启动&无限后台运行&监听进程

    一般来说, IOS很少给App后台运行的权限. 仅有的方式就是 VoIP. IOS少有的为VoIP应用提供了后台socket连接,定期唤醒并且随开机启动的权限.而这些就是IOS上实现VoIP App的 ...

  6. iOS开发之使程序在后台运行

    方法一(此方法不太可靠): 开启程序后台运行: [application beginBackgroundTaskWithExpirationHandler:^{ //后台运行过期后会调用此block内 ...

  7. nohop以及后台运行的相关集合

    本文参考:https://blog.csdn.net/u011095110/article/details/78666833 1. 后台运行一个命令: & tar -czvf /mnt/aa. ...

  8. centos shell基础 alias 变量单引号 双引号 history 错误重定向 2>&1 jobs 环境变量 .bash_history source配置文件 nohup & 后台运行 cut,sort,wc ,uniq ,tee ,tr ,split, paste cat> 2.txt <<EOF 通配符 glob模式 发邮件命令mail 2015-4-8 第十二节课

    centos shell基础知识 alias  变量单引号 双引号   history 错误重定向 2>&1  jobs  环境变量 .bash_history  source配置文件 ...

  9. nohup- Shell后台运行

    &方式: Unix/Linux下一般想让某个程序在后台运行,很多都是使用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台:          /usr/local/my ...

随机推荐

  1. 部署第一个servlet应用到tomcat上

    部署第一个servlet应用到tomcat上 搭建环境 eclipse的EE版本 eclipse官网 创建一个java的应用程序 1.File->new java project 导入servl ...

  2. 搜索专题: HDU1372Knight Moves

    Knight Moves Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tot ...

  3. antd组件Upload实现自己上传

    前言 在实现图片上传时,可能需要用到Upload,但是它默认的上传方式是加入图片后直接上传,如果要实现最后再一次性上传,需要自定义内容. //添加按钮的样式 const uploadButton = ...

  4. linux安装mysql8(完整图文笔记)

    基本命令 安装 : yum install mysql-community-server 启动 : service mysqld start/restart 停止 : service mysqld s ...

  5. 剑指offer-动态规划-贪心算法--剪绳子-python

    题目描述 给你一根长度为n的绳子,请把绳子剪成m段(m.n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],...,k[m].请问k[0]xk[1]x...xk[m]可能 ...

  6. ASP.NET的面包屑导航控件、树形导航控件、菜单控件

    原文:http://blog.csdn.net/pan_junbiao/article/details/8579293 ASP.NET的面包屑导航控件.树形导航控件.菜单控件. 1. 面包屑导航控件— ...

  7. java中使用SimpleDateFormat实现字符串和日期的相互转换

    java中使用SimpleDateFormat实现字符串和日期的相互转换 import java.text.ParseException; import java.text.SimpleDateFor ...

  8. [七月挑选]Tomcat使用命令行启动之指定jdk版本

    title: Tomcat使用命令行启动之指定jdk版本 准备好环境,jdk和tomcat. 主要步骤 1.找到Tomcat/bin/catalina.bat文件. 2.在文件前端添加如下. set ...

  9. Ruby下安装cocoapods

    常规安装:(文末:特殊安装) 注: 1.Mac OS X EI Capitan 10.11中需要更改安装路劲: sudo gem install -n /usr/local/bin cocoapods ...

  10. 2019-8-31-MobaXterm-使用代理

    title author date CreateTime categories MobaXterm 使用代理 lindexi 2019-08-31 16:55:58 +0800 2018-02-13 ...