在項目中有這么一種需求
需要后台開啟服務,時刻記錄用戶和軟件的交互行為,一旦交互發生,就向服務器測發送一條消息
解決方案:
一、創建一個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(); } }