Binder 是一种进程间通信系统,可让 Android 设备上的两个进程进行通信。 Binder 提供了一种在另一个进程中执行函数调用的方法,而调用方完全不知道这一点。
在 Binder 术语中,调用进程被视为客户端,其 端点称为Binder 代理或代理。相反, 被调用的进程是服务器,其端点称为 Binder 节点或节点。
每个节点都可以公开和实现自己的接口。并且,使用代理时,客户端可以对节点接口执行方法,就像调用是本地函数调用一样。以下示例展示了如何调用方法:
int result = someNodeInterface.foo(a, b); // someNodeInterface is a proxy object
假设调用 foo() 的客户端在进程 A 中运行,而实现 foo() 的服务器在进程 B 中运行。图 1 展示了此调用的执行方式:
图 1. Binder 调用执行。
如需在另一个进程中执行方法(如图 1 所示),请执行以下操作:
- 进程 A 中的客户端代码调用进程 A 中的代理代码。进程 A 中的代理代码会创建一个包含以下项的事务:
- 节点的标识符
- 节点上
foo()方法的标识符 - 包含实参
a和b的副本的缓冲区
- 事务会提交给 Binder 内核驱动程序。
- Binder 内核驱动程序确定进程 B 托管节点。
- 内核会将整个事务复制到进程 B 的地址空间中。
- 内核会在进程 B 中找到一个线程来处理事务,并将事务传递给该线程。
- 该线程会解压缩事务,找到节点,并将事务发送到节点对象。
- 节点对象会从事务中获取函数标识符,
从事务缓冲区中解压缩
a和b,并将a和b存储在 局部变量中。 - 节点对象会对进程 B 中的服务器代码调用
foo(a, b)。 - 调用的结果会在回复事务中返回,该事务会传递给内核驱动程序,然后返回给进程 A 中的调用代理。
- 代理会将该结果返回给进程 A 中的调用方。
Binder 应用场景
在不同进程中的软件之间必须进行通信的各种场景中,都可以使用 Binder。例如:
相机应用使用 Binder 与另一个进程中的相机服务器通信。然后,相机服务器使用 Binder 与另一个进程中的相机 HAL 通信。
应用使用 Binder 与另一个进程中的系统服务器通信。系统服务器使用 Binder 与其他进程中的 HAL 通信。
一个进程中的应用使用 Binder 与另一个进程中的不同应用通信。
负责安装、更新和移除应用的系统守护进程 (
installd) 使用 Binder 与 Android 运行时守护进程 ('artd') 通信,以编译应用。
AIDL 和 Binder
使用 Android 接口设计语言 (AIDL) 定义使用 Binder 进行 IPC 的编程接口。如需了解详情,请参阅 AIDL 概览。