zoukankan      html  css  js  c++  java
  • 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();
        }
    
    }
  • 相关阅读:
    块存储、文件存储、对象存储的区别
    brk 和 sbrk 区别
    【转】海量数据处理:十道面试题与十个海量数据处理方法总结
    C++ STL 里为什么不维护一个 size 成员变量?
    C++对象内存分布详解(包括字节对齐和虚函数表)
    虚函数实现原理
    关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案
    Jerasure 1.2A 中的 C 函数 tips
    C++ qsort() 函数调用时实参与形参不兼容的问题解决
    C语言位运算符:与、或、异或、取反、左移与右移详细介绍
  • 原文地址:https://www.cnblogs.com/bobodeboke/p/3419663.html
Copyright © 2011-2022 走看看