深入理解 Android:Binder 通信机制
Native 层 Binder 通信:
初始化 ProcessState:
单例模式,一个进程只能初始化一次;
构造函数初始化
mDriverFD
参数时,自动调用open_driver()
,打开/dev/binder
设备,它是用于内核进程间通信的虚拟设备;对
open_driver()
返回的mDriverFD
对象,调用nmap()
方法,为 Binder 分配内存用于接收数据;
获取 defaultServiceManager:
defaultServiceManager()
函数内部调用了ProcessState
的getContextObject()
函数;调用
getStrongProxyForHandle()
,根据索引查找对应的资源,返回一个BpBinder
对象(如果不存在则创建);
BBinder/BpBinder:
BBinder
和BpBinder
都继承自IBinder
,BpBinder
是客户端用来与 Server 交互的代理类;Binder 系统通过
handle
标识对应的BBinder
,而BpBinder
构造函数传入的handle
为0
,即表示ServiceManager
对应的BBinder
;
BPServiceManager:
通过
DECLARE_META_INTERFACE
和IMPLEMENT_META_INTERFACE
宏, 利用BpBinder
对象创建BpServiceManager
对象;BpServiceManager
对象的mRemote
变量指向了BpBinder
;
ServiceManager:
集中管理系统所有服务(支持通过字符串查找),并控制权限:
svc_can_register()
判断注册服务的进程是否有权限,allowed
数组定义了具有 root 和 system 权限的进程列表;binder_open()
:调用open()
打开 Binder 设备,并调用mmap()
进行内存映射;binder_become_context_manager()
:调用负责系统 IO 通道管理的ioctl()
函数将handle
设为0
;binder_loop()
:for(;;)
调用ioctl()
和binder_parse()
处理请求;
注册 Service:
上面
defaultServiceManager()
返回的实际上是BpServiceManager
对象;调用
BpServiceManager
的addService()
函数,把请求的数据打包为Parcel
对象,传给BpBinder
对象的transact()
函数 (客户端 Service 需要实现onTransact()
方法);BpBinder
对象的transact()
函数调用了IPCThreadState
的transact()
函数;
通信 (IPCThreadState):
每个线程都有唯一的、不共享的 ThreadLocalStorage(TLS);
每个线程都有一个
IPCThreadState
,而每个IPCThreadState
都有一个接收 Binder 数据的mIn
对象和一个存储发往 Binder 数据的mOut
对象;调用
writeTransactionData()
写入数据:设置binder_transaction_data
的target
为传入的handle
,调用mOut.write()
写入数据;调用
waiteForResponse()
等待响应:while(1)
内部调用talkWithDriver()
,binder_write_read
是和 Binder 设备通信的数据结构;处理
BR_ERROR、BR_TRANSACTION
、BR_DEAD_BINDER
、BR_SPAWN_LOOPER
(需要创建新线程) 等消息;
处理 Dead 事件:
如果要在 Binder 通信中收到 Dead 通知,需要继承
IBinder::DeathRecipient
类,并实现binderDied()
函数;调用
BpBinder
的linkToDeath()
函数可注册通知,调用unlinkToDeath()
可取消注册;IPCThreadState
的executeCommand()
函数在收到BR_DEAP_BINDER
消息后,调用BpBinder
的sendObituary()
函数发通知;
开启并加入线程池:
startThreadPool()
: 创建一个PoolThread
对象,它是IPCThreadState
中定义的Thread
子类;joinThreadPool()
: 调用androidSetThreadSchedulingGroup()
和talkWithDriver()
;
Java层初始化Binder:
IBinder 接口:
内部定义了一个整型的
FLAG_ONEWAY
变量,用于 Java 层 Binder 请求的非阻塞调用(不用等待返回),而 Native 层 Binder 请求是阻塞的;Binder
类和BinderProxy
均实现了IBinder
接口;
服务端 Binder 类:
初始化
gBinderOffsets
对象,它保存了和Binder
相关的 JNI 信息(MethodID
等);注册 JNI 函数;
BinderInternal 类:
专门用于 Binder,内部定义了一个
GcWatcher
类处理 Binder 相关垃圾回收;初始化过程和 Binder 类似,也有
gBinderInternalOffsets
对象;
客户端 BinderProxy 类:
- 除了初始化
BinderProxy
类的 JNI 信息,还有WeakReference
类和Error
类;
Java 层 Binder 通信:
ServiceManager::addService:
调用
BinderInternal.getContextObject()
, 创建 Java 层BinderProxy
对象,它通过 JNI 和 Native 层的BpProxy
挂钩,而BpProxy
的通信目标就是ServiceManager
;调用
IServiceManager.asInterface()
,根据上面的Proxy
对象创建ServiceManagerProxy
对象,他会将请求打包给BpProxy
,最终由BpProxy
发给 Binder 驱动;调用
ServiceManagerProxy.addService()
,内部调用Parcel.writeStrongBuffer()
和BinderProxy.transact()
, 最终还是会调用 Native 层的BinderProxy.transact()
;Parcel.writeStrongBuffer()
添加的实际上是一个JavaBBinder
对象;
JavaBBinder/JavaBBinderHolder/Binder:
Native 的
JavaBBinder
通过mObject
变量指向 Java 层Binder
; 收到请求时调用绑定的 Binder 层onTransact()
方法;Java 层
Binder
通过mObject
变量指向 Native 的JavaBBinderHolder
;JavaBBinderHolder
通过mBinder
变量指向JavaBBinder
,它仅从RefBase
派生;
ServiceManager 响应客户端 Binder 请求:
调用 Binder
类的 execTransact()
方法,内部调用 onTransact()
方法,具体 Sercvice 需实现这个方法;
参考: