Understanding Android Source: Binder Library
起源
Android Binder的前身是OpenBinder,已经于2014年10月合并入Linux主线,得到Linux阵营的认可。
其可以理解为一种面向对象的远程调用,其优势有:
- 无需关心线程同步;
- 无需关心内存分配;
Binder Library
Binder进程间通信机制里,有四个大类/接口发挥着关键作用:
IInterfaceIBinderProcessStateIPCThreadState
IInterface
Service组件和Client组件分别使用模板类BnInterface和BpInterface来描述,二者都继承自IInterface,且都是模板类,其模板参数INTERFACE是一个进程自定义的Service组件接口。
BnInterface继承自BBinder,并借助了后者抽象的进程间通信接口。BpInterface继承自BpRefBase,并同样借助了其抽象的进程间通信接口。
理解IInterface相关类,有两个宏非常重要:DECLARE_META_INTERFACE、IMPLEMENT_META_INTERFACE。通过前者,每个接口将会有一个static变量 descriptor,还有一个方法asInterface。
asInteface方法是把IBinder对象转换成IInterface对象,分两种情况:
- 在Client进程中调用,则会新创建一个
BpBinder,其关联了binder_ref。 - 在Service进程中调用,则会返回参数的指针,因为在Service进程中可以直接调用服务类。
IBinder
IBinder定义了进程间通信接口,transact是其重要的成员方法。
BBinder是服务提供者,Binder服务类必须继承自它。成员函数onTransact是由其子类来实现的,负责分发与业务相关的进程间通信请求。
BpBinder是Binder服务在客户端的代表/代理。其成员变量mHandle是标示一个Client组件的句柄值,而这个值也正是Binder驱动程序中binder_ref的desc。
由此,当Client组件通过BpBinder的mHandle,经由Binder驱动程序找到对应的binder_ref,并由其成员node找到对应的binder_node,最后找到要访问的Service组件。
ProcessState
每个进程只有一个ProcessState对象实例,负责管理客户进程中所有的BpBinder,负责创建和释放。Binder线程池中每个线程都是通过它来和Binder驱动程序建立连接。
ProcessState在其构造函数中,完成了两个重要事情:
- 调用
open_binder打开binder设备; - 调用
mmap在驱动中分配内存空间,用于Binder驱动中接收传递给本进程的Binder数据。
设备文件/dev/binder映射到进程的地址空间后,得到的内核缓冲区的用户地址就保存在其成员变量mVMStart中。
IPCThreadState
无论是BnInterface,还是BpInterface,它们都是要通过IPCThreadState类和Binder驱动打交道,每个Binder线程都会关联一个该对象,发送和接收Binder数据,处理和驱动之间的消息。其四个成员函数非常重要:
waitForResponsejoinThreadPooltalkWithDriverexecuteCommand
IPCThreadState和Binder驱动之间通过ioctl来传递数据,其中三个命令非常关键:
BINDER_WRITE_READ- 向驱动读取和写入数据,既可以单独读或写,也可以同时读和写,通过命令中的数据中有无读写数据来控制。关联的结构体是
binder_write_read和binder_transcation_data BINDER_SET_CONTEXT_MGR- 将本进程设置为Binder管理进程,只有ServiceManager进程才会使用这个命令。
BINDER_THREAD_EXIT- 通知驱动当前线程要退出,以便驱动清理和该线程有关系的数据。

粤公网安备44030702004956号