Android后台服务-service

来源:互联网 发布:展翅高飞软件下载 编辑:程序博客网 时间:2024/04/29 17:47

一. 概述
1) 所有耗时和阻塞的操作都应该在service中开启单独线程来处理,每一个任务都要有一个对应的service类,之所以放在service中处理其一是因为它能够保证用户在按下后退back键和home主屏幕键时仍然能够完成任务,不用担心被中断的情况;其二把处理后台任务的应用逻辑和处理用户界面的代码分离,实现解耦。
2) 应用场景:处理后台操作,下载,网络获取,播放音乐。
3)后台:其本身的运行并不依赖于用户可视的UI界面,且具有较长时间的运行特性。
二. 类型与生命周期
这里写图片描述
**类型一:**local service 本地服务-Started Service:context.startService() -> onCreate()【只有首次创建时调用一次】 -> onStartCommand()【服务开启后,多次反复调用】-> Service running -> context.stopService() -> onDestroy() -> Service stop
注意:
1) onStartCommand函数原型
这里写图片描述
注释:
1.1. 返回值返回一个整形常量,用来告诉系统如何处理service的重启操作,三种返回方式,要谨慎处理,不然会导致不可预见的结果

1.2.值一:START_STICKY,当内存不足,系统意外关闭service,接下来未来的某个时间内,当系统内存足够可用的情况下,系统将会尝试重新创建此Service,一旦创建成功后将回调onStartCommand(…)方法,但其中的Intent将是null,pendingintent除外,比如音乐播放器。

1.3.值二:START_NOT_STICKY,一次性操作,上传东西到服务器,即使系统内存足够可用,系统也不会尝试重新创建此Service并重复之前的操作和连接。除非程序中Client明确再次调用startService(…)启动此Service

1.4.值三:START_REDELIVER_INTENT,当系统重启时。会收到service被销毁之前接收到最后一个intent

1.5.参数flags:标志位,标志本次启动请求;

2)onCreate( )和onDestiny( )是相互匹配的,当用户强制杀掉进程时,onDestroy()是不会执行的。当Service因为内存不足而被系统kill这一条件是非常重要的,而透过Context. stopService(Intent service) 和Service. stopSelf()回调了onDestroy()方法则即使系统内存足够可用,Service也不会重启,且无需对当前service是否有效作判断,。没有像activity那样由用户操作直接触发的回调(onPause)
简单地生命周期。

3)通信方式:这种完全解耦的方式,client端非要得到service里处理的结果,最好是借助于发送广播【前提是客户端必须注册广播】。

4 ) onCreate() : 创建耗时的对象,初始化,获取系统服务,注册BroadcastReceiver,初始化新的handler对象

5 ) onDestroy() : 清理操作,停止所有启动的HandlerThread对象,注销之前注册的BroadcastRecevier,耗时的清理工作也应该开启一个线程来执行,AsyncTask关闭网络服务器,存储service的内部状态。

类型二:remote service 远程服务【service处于单独的进程中】-Bound Service :Service的生命周期是依附于Client的生命周期的,当Client不存在时,Bound Service将执行onDestroy,同时通过Service中的Binder对象可以较为方便进行Client-Service通信。

1)生命周期:context.bindService(Intent service,ServiceConnection conn,int flags) -> onCreate() -> onBind(Intent intent) -> Service running -> onUnbind(Intent intent) -> onDestroy() -> Service stop

2)onBind模型
这里写图片描述

3)通信方式:通过获取的Binder实例进行Service端其他公共方法的调用,以完成Client-Service通信。

4)编程步骤
方式一:Clinet与Service必须同属于同一个进程,不能实现进程间通信(IPC)。否则则会出现类似于“android.os.BinderProxy cannot be cast to xxx”错误【.Extending the Binder class】

4.1. 新建Service类BindService。
public class MyBinder extends Binder{
public BindService getService(){
return BindService.this;
}
}
实例化MyBinder得到mybinder对象;
重写onBind()方法:
@Override
public IBinder onBind(Intent intent) {
return mybinder;
}

4.2. 在Activity里,实例化ServiceConnection接口的实现类,重写onServiceConnected()和onServiceDisconnected()方法
ServiceConnection conn=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取Service端Binder实例
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};

4.3. 在Activity的onCreate()方法里,新建Intent,并绑定服务
Intent intent=new Intent(MainActivity.this,BindService.class);
bindService(intent, conn,BIND_AUTO_CREATE);

4.4. 在Activity的onDestroy里面,添加unbindService(conn);

4.5.执行流程:bindService(intent,conn,flag)->Service:onCreate()->Service:onBind()->Activity:onServiceConnected()

方式二:Using a Messenger,Messenger,在此可以理解成”信使“,通过Messenger方式返回Binder对象可以不用考虑Clinet - Service是否属于同一个进程的问题,并且,可以实现Client - Service之间的双向通信

方式三:.AIDL(Android Interface Definition Language)

三. 继承结构
1) 其本质就是context,很多子类,提供不同的服务。
这里写图片描述
2)使用技巧:前台service【onStartCommand中调用startForeground;onDestroy中调用stopForeground解除前台运行】结合notification界面使用。

参考文档:
http://www.cnblogs.com/lwbqqyumidi/p/4181185.html
http://www.cnblogs.com/yejiurui/archive/2013/11/18/3429451.html
http://blog.csdn.net/ryantang03/article/details/7770939
http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html

四. IntentService
1)onHandlerIntent(..)主要就是用来处于相应的”长期“任务的,并且已经自动在新的线程中,用户无语自定义新线程,此IntentService将自动结束,无需人为调用方法使其结束,非并发处理。

五. ExecutorService
“未完待续。。。”

0 0
原创粉丝点击