?
使用的是plantUML生成的,脚本如下:
@startuml
autonumber
title bindService之拿到服务端的binder
App绑定服务 -> ContextImp: bindService// 服务端的binder对象最终回调到onServiceConnected中
ContextImp -> ContextImp: bindServiceCommon
ContextImp -> LoadedApk:getServiceDispatcher():IServiceConnection
ContextImp -> ActivityManager: getService():ActivityManagerService
ContextImp -> ActivityManagerService: bindIsolatedService
ActivityManagerService -> ActiveServices:bindServiceLocked()
ActiveServices -> ActiveServices:retrieveServiceLocked// 从PackageManager中得到服务端对应的ServiceRecord
ActiveServices -> ActiveServices:bringUpServiceLocked//如果是autoCreate的flag的话调用这个方法,会开始创建服务,\n并在ActivityThread中的mServices里面管理
ActiveServices -> ActiveServices: 检查权限和参数
ActiveServices -> ConnectionRecord:构造方法(connection:IServiceConnection)
ActiveServices -> IServiceConnection:asBinder():连接LoadApk的内部类对象:InnerConnection赋值给service
group 冷启动服务
ActiveServices-> ActiveServices:requestServiceBindingLocked
ActiveServices -> ActivityThread.ApplicationThread: scheduleBindService
ActivityThread.ApplicationThread -> ActivityThread: handleBindService
ActivityThread -> Service:onBind(data.intent)// 得到服务端binder,
ActivityThread -> ActivityManagerService: publishService
ActivityManagerService -> ActiveServices: publishServiceLocked
ActivityManagerService -> LoadedApk.ServiceDispatcher.InnerConnection: connect()
LoadedApk.ServiceDispatcher.InnerConnection -> LoadedApk.ServiceDispatcher:doConnected
LoadedApk.ServiceDispatcher -> ServiceConnection:onServiceConnected(name, binder)
end
@enduml
看了下源代码,梳理了上面流程,主要是解答我一直以来的困惑,就是这个binderService怎么就能拿到服务端的binder呢?他怎么就算是跨进程呢?
梳理完后,其实就是ActiveServices和ActivityThread和PackageMangerService把服务端的binder找出来。如果没有就创建,然后调用这个服务的onBind方法。如果已经绑定过了,就直接把缓存中的binder对象拿出来回调到客户端,所以很多个客户端拿到的都是同一个binder。
?发现一个写得挺好挺详细的博客,可以跟着这个博客看源码:(57条消息) 由浅入深 学习 Android Binder(一)- AIDL_许佳佳的博客-CSDN博客https://blog.csdn.net/Double2hao/article/details/109865496
下一篇打算找找为什么拿到的binder对象可以用客户端那个接口来强转,它不是两个接口文件吗?这样也能强转吗?还有就是为什么说binder只用复制一次的,到底是在哪里复制的呢?
|