匿名binder不会存储ServiceManager里面,所以没法通过getService查询,来看看常用的bindService是如何获取一个匿名Binder的
匿名Binder的创建
应用层传输逻辑
以Service中的onBind函数返回一个binder对象为例子,我们先画下时序图
sequenceDiagram
note over App1,AMS:IPC 到system_server【1】
App1 ->> AMS:bindService
AMS ->> ActiveService:bindServiceInstance
ActiveService -->>ActiveService:bindServiceLocked
ActiveService -->>ActiveService:requestServiceBindingLocked
note over ActiveService,ActivityThread:IPC 到app2
ActiveService -->> ActivityThread:scheduleBindService
ActivityThread -->> ActivityThread:handleBindService
ActivityThread -->> Service:onBind
Service -->> ActivityThread:返回Binder
note over ActivityThread,AMS:IPC 到system_server 【2】
ActivityThread ->> AMS:publishService(binder)
AMS ->> ActiveService:publishServiceLocked
ActiveService -->> App1:onServiceConnected
note over ActiveService,App1:这里通过ServiceDispatcher封装的ServiceConnection接口返回
内核创建binder_node
IPC 到system_server 【2】:这是一次以Service为客户端AMS为服务端的IPC传输,函数参数带binder, 在内核函数binder_transaction中解析binder数据时,发现携带了binder对象,于是查找当前发起进程(Service)的binder_proc树中是否有和这个Binder对象对应的binder_node节点,如果没有,那就创建一个binder_node,并且插入到binder_proc所在的binder实体红黑树中,同时创建对应的binder_ref节点,最终返回给AMS接口中的binder就是一个binder代理,指向了Service中的binder, AMS最后会把这个binder代理对象返回给客户端App1
所以,客户端拿到这个binder发起binder调用时,内核会通过这个binder代理查找对应的binder_node并且找到它对应的进程,然后唤醒进程的binder线程去发起函数调用。
参考连接
IBinder转换为BinderProxy函数分析:javaObjectForIBinder和ibinderForJavaObject源码分析android28 系统源码 - 掘金