在项目中有这么一种需求

需要后台开启服务,时刻记录用户和软件的交互行为,一旦交互发生,就向服务器测发送一条消息

解决方案:

一、创建一个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();
} }

android 后台运行service实现和后台的持续交互的更多相关文章

  1. 在后台运行erlang;在需要时连回交互模式

    * 1. 启动后台运行的erlang环境 按以下命令: erl -detached -name a@127.0.0.1 注意,-name的值必须是xxxx@ip的形式.其中xxxx是英文名,ip必须是 ...

  2. Android长时间后台运行Service

         项目需要在后台获取GPS经纬度.当用户对手机有一段时间没有操作后,屏幕(Screen)将从高亮(Bright)变为暗淡(Dim),如果再过段时间没操作, 屏幕(Screen)将又由暗淡(Di ...

  3. Android课程---关于Service的学习(后台运行)

    MainActivity.java package com.hanqi.test2; import android.content.ComponentName; import android.cont ...

  4. iOS7程序后台运行

    介绍 这次 iOS7 对程序后台运行进行了加强,但是仅仅是加强而已,要想像 Android 程序那样自由当然就别想了,苹果这么做主要还是出于电池使用时间考虑,但是这次的加强对大部分程序基本够用. 在介 ...

  5. IOS高级开发~开机启动&无限后台运行&监听进程

    一般来说, IOS很少给App后台运行的权限. 仅有的方式就是 VoIP. IOS少有的为VoIP应用提供了后台socket连接,定期唤醒并且随开机启动的权限.而这些就是IOS上实现VoIP App的 ...

  6. iOS开发之使程序在后台运行

    方法一(此方法不太可靠): 开启程序后台运行: [application beginBackgroundTaskWithExpirationHandler:^{ //后台运行过期后会调用此block内 ...

  7. nohop以及后台运行的相关集合

    本文参考:https://blog.csdn.net/u011095110/article/details/78666833 1. 后台运行一个命令: & tar -czvf /mnt/aa. ...

  8. centos shell基础 alias 变量单引号 双引号 history 错误重定向 2>&1 jobs 环境变量 .bash_history source配置文件 nohup & 后台运行 cut,sort,wc ,uniq ,tee ,tr ,split, paste cat> 2.txt <<EOF 通配符 glob模式 发邮件命令mail 2015-4-8 第十二节课

    centos shell基础知识 alias  变量单引号 双引号   history 错误重定向 2>&1  jobs  环境变量 .bash_history  source配置文件 ...

  9. nohup- Shell后台运行

    &方式: Unix/Linux下一般想让某个程序在后台运行,很多都是使用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台:          /usr/local/my ...

随机推荐

  1. bits,Bytes,KB,MB,GB和TB之间的换算关系

    1Bytes=8bits(1字节等于8位) 1KB=1024Bytes(1KB等于1024字节) 1MB=1024KB 1GB=1024MB 1TB=1024GB 为啥带宽100M而下载大概只是12. ...

  2. @-webkit-keyframes 动画 css3

    Internet Explorer 10.Firefox 以及 Opera 支持 @keyframes 规则和 animation 属性. Chrome 和 Safari 需要前缀 -webkit-. ...

  3. 数位DP 计划

    通常的数位dp可以写成如下形式: [cpp] view plain copy int dfs(int i, int s, bool e) { if (i==-1) return s==target_s ...

  4. 搜索专题: HDU1429胜利大逃亡

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  5. pip和pip3的区别

    安装了python3之后,会有pip3 1. 使用pip install XXX 新安装的库会放在这个目录下面 python2.7/site-packages 2. 使用pip3 install XX ...

  6. 【问题解决方案】CentOS7替换yum的问题:使用yum makecache出现File contains no section headers

    参考链接 CentOS7替换yum的问题:使用yum时出现File contains no section headers centos安装网络repo源及错误说明 一.centos替换yum的步骤 ...

  7. CenterOS7中解决No package mysql-server available.

    CenterOS7中解决No package mysql-server available. 1.使用yum install -y mysql-server报错如下: [root@heyong_jd ...

  8. 使用idea实现SSM框架整合

    SM框架整合 1      使用idea创建一个maven webapp项目 到此为止项目初步建立,需要等待maven对项目结构进行组织,直到状态栏的进度条完成,且项目的目录结构如下: 2      ...

  9. linux MySql 主从异步复制

    [root@localhost ~]# hostname master.allentuns ###SLAVE 执行 [root@localhost ~]# sed -i 's@\(HOSTNAME=\ ...

  10. mysql的索引以及优化

    本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29Lo ...