[划重点] Service 知识要点

栏目: IOS · Android · 发布时间: 5年前

内容简介:来总结一下 Service 的几个知识要点,包括启动方式、每种启动方式的生命周期、IntentService 源码分析,以及 boundService 三种使用方法。注:API 大于等于 26 时,当 app 不在前台的时候,后台服务会受到限制,这种情况下,官方文档推荐使用 Schedule jobs。startService(): onCreate() -> onStartCommand()/onStart() -> … -> onDestroy()

来总结一下 Service 的几个知识要点,包括启动方式、每种启动方式的生命周期、IntentService 源码分析,以及 boundService 三种使用方法。

Service 三种启动方式

  1. 前台 Service (startForegroundService(intent)): 在 API 大于等于 26 以上,用来设置通知栏。在调用这个 api 之后应马上调用 Service#startForeground(int, Notification),来设置 Notification,否则系统会自动停止 Service,并发生 ANR。

  2. 后台 Service (startService(intent)): 如果 app 的一些操作不需要通知用户,则启动后台 Service。

注:API 大于等于 26 时,当 app 不在前台的时候,后台服务会受到限制,这种情况下,官方文档推荐使用 Schedule jobs。

  1. 绑定 Service (bindService(intent, serviceConnection, flags)): 绑定 Service 提供客户端/服务端模式,组件之间可以用过它发送、接受消息,甚至可以跨进程通信。在调用 unbindService(),Service 就会销毁。

生命周期

startService(): onCreate() -> onStartCommand()/onStart() -> … -> onDestroy()

bindService(): onCreate() -> onBind() -> … -> onUnbind() -> onDestroy()

以上两个生命周期只是对单个 activity start 或者 bind 服务的时候,然而在实际使用的时候,通常会两个结合使用,也或者是多个 activity 对同一个 service 绑定。

  1. 多个 Activity StartService 时,Service 不会重复启动,onStartCommand() 会重复执行,并获取对应的 intent。当有一个 stopService() 时,Service 会销毁。
  2. 多个 Activity 绑定和解绑时,Service 会重复走 onBind()/onUnbind()这两个生命周期,但不会销毁,直到没有 Activity 和它有绑定关系的时候,才会销毁。
  3. 当 StartService/bindService 混合用时,Service 的销毁时机为 stopService。

[划重点] Service 知识要点

IntentService 原理

大家都知道,IntentService 的特性是运行在非 UI 线程,可执行耗时操作,当执行完后会自动销毁。我们今天在看一下它的原理:

IntentService 内部由 HandlerThread 维护一个线程,在启动后获取 intent 并发送给 HandlerThread 所在的线程执行,执行完任务后自动调用 stopSelf() 销毁。

具体的源码实现如下:

  1. 继承 Service;
  2. onBind(): IntentService 由 startService() 启动,当然不需要 binder,所以这个函数返回 null;
  3. onCreate(): 新建 HandlerThread 并启动线程,通过 HandlerThread.getLooper() 新建 Handler。总结起来两句代码,大致如下:

    new HandlerThread().start();
    new ServiceHandler(thread.getLooper());
    
  4. onStart(): 这个函数中,通过前面新建的 Handler,把 intent 消息发送到非 UI 线程,即:mServiceHandler.sendMessage(msg)。

  5. ServiceHandler 的 handleMessage 函数实现中,先执行抽象函数 onHandleIntent,此函数中即是我们想要在 IntentService 中执行的任务。在函数执行结束后调用 stopSelf(msg.arg1) 终止服务,这也就是为什么任务执行完毕后会自动销毁的原因。
  6. onDestroy(): 在此方法中退出之前创建的线程,即:mServiceLooper.quit()。

boundService 三种使用方法

  1. 继承 Binder:实现内部类继承 Binder,并在 onBind() 中返回。此中方法不能实现 IPC。
  2. 使用 Messenger:Messenger 服务端需要传入 Handler 做参数,因此在 Service 中实现 Handler 内部类,创建 Messenger,并在 onBind() 中返回 mMessenger.binder。客户端通过 IBinder 作为参数新建 Messenger 实例,这样便可与服务端通信。Messenger 内部实现使用 Binder,支持 IPC,因此此中方式可用于跨进程通信。
  3. AIDL:新建 AIDL 文件,编译器会自动生成对于的 java 类,之后在 Service 实现自动生成类的接口方法,onBind() 方法中返回实现类的 asBinder() 方法,客户端中在 ServiceConnection 回调中通过 asInterface(IBinder) 获取到远端类通信。

关于 AIDL、Binder 的相关知识,为想单拿出一篇博客来说,所以这里就先简单说一下使用方法。欢迎关注我的微信公众平台(码小猪),如有更新会及时发布。

[划重点] Service 知识要点


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Complexity and Approximation

Complexity and Approximation

G. Ausiello、P. Crescenzi、V. Kann、Marchetti-sp、Giorgio Gambosi、Alberto M. Spaccamela / Springer / 2003-02 / USD 74.95

This book is an up-to-date documentation of the state of the art in combinatorial optimization, presenting approximate solutions of virtually all relevant classes of NP-hard optimization problems. The......一起来看看 《Complexity and Approximation》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换