深入理解 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 需实现这个方法;
参考: