前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[划重点] Service 知识要点

[划重点] Service 知识要点

作者头像
haifeiWu
发布2020-02-10 17:48:28
6920
发布2020-02-10 17:48:28
举报

来总结一下 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_binding_tree_lifecycle
service_binding_tree_lifecycle

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) 获取到远端类通信。

作 者:ChanghuiN 原文链接:https://www.hchstudio.cn/article/2019/9f46/ 版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Service 三种启动方式
  • 生命周期
  • IntentService 原理
  • boundService 三种使用方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档