1. Binder基础
Binder 是 Android 系统中进程间通信(IPC)的核心机制,也是整个系统架构的“神经网络”。理解 Binder 的定位、设计取舍与通信模型,是后续进行性能优化的前提。
1.1 Binder在Android系统中的定位
Android 系统基于 Linux 内核,但并未直接使用 Linux 原生的 IPC 机制(如管道、Socket、System V IPC)作为主要通信手段,而是自研了 Binder 驱动。Binder 在系统架构中处于承上启下的关键位置:
- 应用层:ServiceManager、ActivityManagerService、WindowManagerService 等核心服务均通过 Binder 暴露接口。
- 框架层:Java 层的
IBinder、Binder、BinderProxy封装了底层驱动交互。 - Native 层:libbinder 库提供 C++ 接口,
ProcessState、IPCThreadState管理线程与驱动通信。 - 内核层:
binder_driver负责数据拷贝、线程管理、节点查找与引用计数。
关键认知: Binder 不是简单的“另一种 IPC”,它是 Android 系统面向对象设计思想的延伸——将远程服务调用伪装成本地方法调用,同时解决了传统 IPC 的性能与安全问题。
1.2 Binder与Socket/共享内存的对比
Android 选择 Binder 而非传统 IPC 方案,是基于性能、安全与易用性的综合权衡。下表从多个维度进行对比:
| 对比维度 | Binder | Socket (Unix Domain) | 共享内存 (ashmem) |
|---|---|---|---|
| 数据拷贝次数 | 1 次(内核 mmap 映射) | 2 次(用户态→内核→用户态) | 0 次(直接映射,需同步) |
| 传输模式 | 同步/异步 RPC | 流式/数据报 | 共享内存块 |
| 安全机制 | 内核级 UID/PID 校验 + 实名/匿名绑定 | 需应用层自行校验 | 无内置校验 |
| 面向对象支持 | 原生支持(接口、回调、继承) | 需自行序列化/反序列化 | 不适用 |
| 线程模型 | Binder 线程池 + 驱动调度 | select/poll/epoll 事件驱动 | 需应用层管理锁与同步 |
| 典型场景 | 系统服务调用、跨进程方法调用 | 网络通信、低频率 IPC | 大块数据共享(如 SurfaceFlinger) |
性能要点: Binder 的“1 次拷贝”是其性能优势的核心来源。传统 Socket 需要 2 次拷贝(发送方用户态→内核→接收方用户态),而 Binder 通过 mmap 在内核与接收方用户态之间建立共享映射,发送方数据只需拷贝到内核缓冲区一次,接收方即可直接读取。
1.3 Binder的C/S架构模型
Binder 采用经典的客户端-服务器(Client-Server)架构,但与传统 C/S 模型相比,增加了 ServiceManager 作为服务注册与发现中心,以及 Binder 驱动 作为内核级传输与调度实体。
1.3.1 核心角色
- Client(客户端):发起服务请求的进程,通过 Binder 代理(BpBinder)调用远程方法。
- Server(服务端):提供具体服务的进程,通过 Binder 实体(BBinder)接收并处理请求。
- ServiceManager(服务管理器):系统级守护进程,维护服务名称到 Binder 引用的映射表。
- Binder Driver(驱动):内核模块,负责数据传递、线程调度、引用计数与安全校验。
1.3.2 一次完整Binder调用流程
- 服务注册:Server 进程向 ServiceManager 注册服务(如 "activity"),ServiceManager 记录其 Binder 引用。
- 服务获取:Client 进程向 ServiceManager 查询服务名称,获得目标服务的 Binder 代理。
- 方法调用:Client 通过代理发起
transact()调用,数据打包为Parcel后写入 Binder 驱动。 - 驱动转发:Binder 驱动根据目标句柄找到 Server 进程的 Binder 实体,将数据拷贝到 Server 的 mmap 缓冲区。
- 请求处理:Server 的 Binder 线程池从驱动读取请求,调用对应方法,将结果写回驱动。
- 结果返回:驱动将结果拷贝到 Client 的缓冲区,Client 线程被唤醒,读取返回数据。
性能陷阱: 每次 Binder 调用都涉及用户态→内核态→用户态的上下文切换。高频小数据量调用(如频繁读取系统属性)会导致显著的上下文切换开销,这是后续优化章节的重点关注对象。
1.4 小结:Binder的设计哲学
Binder 并非追求“绝对最快”的 IPC,而是在 性能、安全、易用性 三者之间取得了最佳平衡:
- 性能:1 次拷贝 + mmap 映射,远优于 Socket 的 2 次拷贝;同步调用模型简单高效。
- 安全:内核级 UID/PID 校验,每个 Binder 调用都携带身份信息,无需应用层额外处理。
- 易用性:面向对象接口设计,AIDL 自动生成桩代码,开发者只需关注业务逻辑。