[划重点] Service 知识要点

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

内容简介:来总结一下 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 知识要点


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

查看所有标签

猜你喜欢:

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

Pro Git

Pro Git

Scott Chacon / Apress / 2009-8-27 / USD 34.99

Git is the version control system developed by Linus Torvalds for Linux kernel development. It took the open source world by storm since its inception in 2005, and is used by small development shops a......一起来看看 《Pro Git》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码