Android unbindService流程与BIND_AUTO_CREATE详解
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
- 任意一个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()
最终关闭服务。