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();
    }

}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM