android 后台运行service实现和后台的持续交互
在项目中有这么一种需求
需要后台开启服务,时刻记录用户和软件的交互行为,一旦交互发生,就向服务器测发送一条消息
解决方案:
一、创建一个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(); } }