Binder 是 Android 系统中最重要的进程间通信(IPC)机制。
1. 为什么 Android 选用 Binder?
在 Linux 系统中,已经存在多种 IPC 方式,如管道、信号、消息队列、共享内存、Socket 等。Android 选用 Binder 主要出于以下考虑:
- 性能(效率):共享内存虽然最快(0 次拷贝),但管理复杂;Socket 效率低(2 次拷贝);Binder 只需要 1 次数据拷贝,性能仅次于共享内存。
- 安全:传统 IPC 的接收方无法获得发送方可靠的 UID/PID,难以进行权限校验。Binder 在内核层添加了身份校验,安全性更高。
- 稳定性:Binder 基于 Client-Server 架构,职责明确,容错性好。
2. Binder 的分层架构
Binder 的实现可以分为四个层次:
- **内核层 (Binder Driver)**:运行在内核空间,是所有 Binder 通信的枢纽。负责物理内存映射(mmap)和数据的跨进程传递。
- **驱动抽象层 (Libbinder)**:在 Native 层对驱动操作进行封装(如
ProcessState,IPCThreadState)。 - **框架层 (Java Binder)**:提供给 Java 开发者使用的接口(如
IBinder,Binder,Stub,Proxy)。 - 应用层:具体的业务实现(如 AIDL 定义的 Service)。
3. Binder 通信的核心:内存映射 (mmap)
Binder 之所以能实现“一次拷贝”,核心在于 mmap。
- Binder 驱动会在内核空间分配一段缓冲区。
- 驱动会将这段内核缓冲区同时映射到接收进程的用户空间。
- 发送进程通过
copy_from_user将数据拷贝到内核缓冲区,由于映射关系存在,接收进程直接就能在自己的用户空间读到这些数据。
4. 总结
Binder 是 Android 系统的灵魂。理解了 Binder,才能真正理解 AMS、WMS 等系统服务是如何与应用进程协同工作的。