Service 四大组件之一主要用于
1> 处理后台耗时逻辑,或者执行某些需要长期运行的任务。
2> 跨进程通信。
Service默认时运行在它所在的宿主进程的主进程中,可能会因为执行耗时操作而导致ANR,做耗时操作需要在 service 中创建新的进程来处理耗时任务。
一、startService / stopService
onCreate() 只会被调用一次;
onStartCommand:如果多次执行了Context的startService方法,那么Service的onStartCommand方法也会相应的多次调用。
onBind:Service中的onBind方法是个抽象方法,所以Service类本身就是一个抽象类,也就是说onBind方法必须要重写,即使用不到。通过startService使用Service时,我们在重写onBind方法时,只需要将其返回值设为null即可。onBind方法主要是用于给bindService方法调用Service时才使用到。
onDestiny:Service销毁时回调函数。
如果Service启动后没有去停止掉它,它会一直运行下去,停止startService启动的Service有两种方法:
1、在外部调用stopService
2、在Service内部调用stopSelf方法
二、关于 onStartCommand 方法
public int onStartCommand(Intent intent, int flags,int startId) {}
1、starId是唯一的,startId默认从1开始,onStartCommand 被多次调用, startId 呈现递增形式,每次加 1.
2、onStartCommand中返回值。(用在保活!!!)
START_NOT_STICKY:表示当Service运行的进程被android系统强制杀掉之后,不会重新创建该Service,如果想重新实例化该Service,就必须重新调用startService来启动。
START_STICKY:表示Service运行的进程被Android系统强制杀掉之后,Android系统会将该Service依然设置为started状态(即运行状态),但是不再保存onStartCommand方法传入的intent对象。然后Android系统会尝试再次重新创建该Service。(Service 第一次被异常杀死后会在5秒内重启,第二次被杀死会在10秒内重启,第三次会在20秒内重启,一旦在短时间内 Service 被杀死达到5次,则系统不再拉起。)
START_REDELIVER_INTENT:表示Service运行的进程被Android系统强制杀掉之后,与返回START_STICKY的情况类似,Android系统会将再次重新创建该Service,并且保留 Intent 数据信息
三、Service 的封装类 IntentService
IntentService 继承自 Service ,为了简化开发不用再在 Service 中创建工作线程而生。
IntentService特点:
1. IntentService自带一个工作线程,当我们的Service中做一些阻塞UI(主)线程工作时,可以使用IntentService。
2. 将我们实际要做的工作放入到 IntentService 的 onHandleIntent 方法中处理,并且 onHandleIntent 运行在 IntentService 所持有的工作线程中,而非主线程。
3. IntentService 维护有一个单线程任务队列, IntentService当多次启动 IntentService,产生多个 job,IntentService 只能一个一个处理。所有任务处理完后 IntentService 会自行执行销毁操作
四、binderService / unbindService
绑定的目的是为了 客户端(client)与服务端(Service)交互的目的。
绑定服务的具体流程:
4.1 拓展 Binder 类
4.2 实现 ServiceConnection 接口
4.3 调用 bindService(),传递 ServiceConnection 对象
4.4 当系统调用了 onServiceConnected() 的回调方法时,就可以通过IBinder对象操作服务了
4.1 拓展 Binder 类
如果服务仅供本地应用使用,不需要跨进程工作,则可以实现自有 Binder 类,让客户端通过该类直接访问服务中的公共方法。此方法只有在客户端和服务位于同一应用和进程内这一最常见的情况下方才有效
以下是具体的设置方法:
4.1.1 在服务中创建一个可满足下列任一要求的 Binder 实例:
包含客户端可调用的公共方法
返回当前 Service 实例,其中包含客户端可调用的公共方法
或返回由服务承载的其他类的实例,其中包含客户端可调用的公共方法
4.1.2 从 onBind() 回调方法返回此 Binder 实例
4.1.3 在客户端中,从 onServiceConnected() 回调方法接收 Binder,并使用提供的方法调用绑定服务
4.2 实现ServiceConnection 接口
重写两个回调方法:
onServiceConnected()
系统会调用该方法以传递服务的onBind() 方法返回的 IBinder
onServiceDisconnected()
Android 系统会在与服务的连接意外中断时,例如当服务崩溃或被终止时调用该方法。当客户端取消绑定时,系统不会调用该方法
五、定义IBinder接口,及进程间通讯
可以通过以下三种方法定义IBinder接口:
5.1 扩展 Binder 类
如果服务是供本应用专用,并且运行在与客户端相同的进程中,则应通过扩展 Binder 类并从 onBind() 返回它的一个实例来创建接口。客户端收到 Binder 后,可利用它直接访问 Service 中可用的公共方法
5.2 使用 Messenger
如需让接口跨不同的进程工作,则可使用 Messenger 为服务创建接口。服务可以这种方式定义对应于不同类型 Message 对象的 Handler。此 Handler 是 Messenger 的基础,后者随后可与客户端分享一个 IBinder,从而让客户端能利用 Message 对象向服务发送命令。此外,客户端还可定义自有 Messenger,以便服务回传消息。这是执行进程间通信 (IPC) 的最简单方法,因为 Messenger 会在单一线程中创建包含所有请求的队列,这样就不必对服务进行线程安全设计
缺点:这种机制只能互发消息而不能直接调用服务端方法;只能以串行方式处理客户端请求。
5.3 使用 AIDL
AIDL(Android 接口定义语言)执行所有将对象分解成原语的工作,操作系统可以识别这些原语并将它们编组到各进程中,以执行 IPC。 之前采用 Messenger 的方法实际上是以 AIDL 作为其底层结构。 如上所述,Messenger 会在单一线程中创建包含所有客户端请求的队列,以便服务一次接收一个请求。 不过,如果想让服务同时处理多个请求,则可直接使用 AIDL。 在此情况下,服务必须具备多线程处理能力,并采用线程安全式设计。如需直接使用 AIDL,必须创建一个定义编程接口的 .aidl 文件。Android SDK 工具利用该文件生成一个实现接口并处理 IPC 的抽象类,随后可在服务内对其进行扩展
Android中Service使用bindService 简单Demo 代码
比较好的 Service 相关文章
网友评论