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

}

 

 

 

posted @ 2013-11-12 15:39  bobo的学习笔记  阅读(5161)  评论(0编辑  收藏  举报