Service

作者: WLHere | 来源:发表于2020-10-06 22:42 被阅读0次

Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。此外,组件可通过绑定到服务与之进行交互,甚至是执行进程间通信 (IPC)。例如,服务可在后台处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序进行交互。

启动方式

  1. startService
  2. bindService

生命周期

  • onCreate
  • onStartCommand
  • onBind
  • onDestroy

onStartCommand

执行时机

通过startService启动会执行此方法

返回值
  1. START_NOT_STICKY:被杀后不重启
  2. START_STICKY:被杀后重启,会调用onStartCommand,但是intent是null。默认返回这个值
  3. START_STICKY_COMPATIBILITY:被杀后重启,不会调用onStartCommand。只有targetSdkVersion < 5才会默认返回这个值
  4. START_REDELIVER_INTENT:被杀后重启,会调用onStartCommand,会传递最后一个intent

onBind

执行时机

通过bindService启动会执行此方法

返回值

IBinder:通过binder机制实现方法调用

FAQ

  • service生命周期在哪个线程执行?

在UI线程执行。service的生命周期都是由ActivityManagerService&ActiveServices控制,他们通过binder通知ApplicationThread改变生命周期,ApplicationThread收到消息之后发送handler消息去执行service的生命周期方法

  • service生命周期有超时时间吗?是多少?

有。非前台service限制20s,前台service限制20s*10。

  • 一次startService一定对应一次onStartCommand吗?

是的。可能ActiveServices一次发送多个启动任务,ApplicationThread收到之后会依次发送消息去处理。

  • onStartCommand的startId来源

启动的Service对应一个ServiceRecord。ServiceRecord的lastStartId记录上次的启动id。每次启动会调用ServiceRecord.makeNextStartId来返回下一个startId。startId从1开始递增。

  • onStartCommand的返回值作用原理

ActivityThread.handleServiceArgs执行service的onStartCommand方法,并把返回值通过ActivityManager.getService().serviceDoneExecuting最终回调到ActiveServices. serviceDoneExecutingLocked。在此方法里边根据参数决定是否移除ServiceRecord的相应StartItem和设置ServiceRecord.stopIfKilled属性

  • 一次bindService一定对应一次onBind吗?

不是一一对应的。只有service初次绑定才会调用onBind方法,之后ActiveServices会使用记录的IBinder来“返回”给IServiceConnection。

  • context销毁之后自动触发unBindService的原理

以actvitiy为例,ActivityThread.handleDestroyActivity -> ContextImpl.scheduleFinalCleanUp -> ActivityThread.scheduleContextCleanUp -> ContextImpl.performFinalCleanUp -> LoadedApk.removeContextRegistrations。在LoadedApk.removeContextRegistrations会移除尚未取消注册的广播接收器或者尚未取消绑定的service。同时会打印错误日志,例如 * has leaked ServiceConnection * that was originally bound here

  • 检测connection断开
被动回调 ServiceConnection.onServiceDisconnected IBinder.DeathRecipient.binderDied
应用范围 通过binderService获得的binder 任意binder
主动unbind 不调用 不调用
remote process killed 调用 调用
因为context销毁被动unbind 不调用 不调用

主动检测 IBinder.pingBinder IBinder.isBinderAlive 其他自定义Binder方法
正常值 true true 正常
异常值 false false android.os.DeadObjectException
  • 连接池

一个service智能提供一个binder,但是可以通过这个binder提供获取其他binder的能力,避免创建多个service

  • 如何反向调用?

提供方法允许客户端注册binder,即可通过客户端注册的binder调用客户端方法

附-时序图

start service
image.png
stop service
image.png
bind & unbind service
image.png

相关文章

网友评论

      本文标题:Service

      本文链接:https://www.haomeiwen.com/subject/giehektx.html