10:31 am
Thursday, 16 June 2022 (HKT)
Time in Hong Kong


概述

基于Android 10分析bindService(Intent, ServiceConnection, flag)调用中flag传递BIND_AUTO_CREATE与传递0的区别。分析unbindService基本流程。

BIND_AUTO_CREATE

一般调用bindService()时都传递参数BIND_AUTO_CREATE,它让系统自动拉起被绑定的服务。但实际上,该参数可以不传递,而替换为传递0

BIND_AUTO_CREATE会让系统在bind之前首先通过bringUpServiceLocked()先启动服务,并回调服务的onCreate()onStartCommand()。然后再执行onBind()绑定服务后,返回到client的ServiceConection.onServiceConnected()

0则不会启动服务。而必须通过其他方式启动服务(比如调用startService())。

实际上,服务还有被BIND_AUTO_CREATE绑定时就不会退出,否则,如果服务没有绑定或者仅被0绑定了,会被stopService()unbindService()关闭。

总结:bound service不退出的条件是还有BIND_AUTO_CREATE的绑定,而0的绑定不会影响服务退出。

Service只有在首次绑定时才会回调onBind(),后面任何一个client再调用bindService()都不再回调onBind()。这是因为首次绑定中onBind()返回的IBinder已经被系统缓存了,直接返回给client即可。

unbindService

unbindService流程

onUnbind流程

  • 任意一个client发起bind后回调onBind(),此后其他任何client的bind都不再回调
  • 所有client都unbindService()了才会回调onUnbind

unbind调用会移除App侧ServiceDispatcher内记录的ServiceConnection信息,并且在ActiveServices移除相关ConnectionRecord信息。

然后检查Service是否还有client绑定它。当没有绑定时,会回调到服务进程调用onUnbind()

如果服务是bindService(BIND_AUTO_CREATE)拉起的,那么此时就要检查服务是否需要停止(bringDownServiceIfNeededLocked())。如果没有任何client以BIND_AUTO_CREATE绑定服务了,且服务没有被startService()调起来过(ServiceRecord.startRequested),此时会将服务关闭(bringDownServiceLocked())。这一步会从ActiveService内的记录找到所有绑定该服务的client(以0为参数调用的bind),回调这些client的onServiceDisconnected()。然后回调到Service的onUnbind()、移除通知、回调Service的onDestroy()最终关闭服务。

参考

  1. Use 0 or BIND_AUTO_CREATE for bindService’s flag
  2. Android Developer绑定服务概览
  3. Android Developer服务概览