Binder是Android系统中最核心、最高效的进程间通信(IPC)机制,承担了系统90%以上的跨进程通信任务。它的设计兼顾了高性能 和高安全性,是Android系统架构的基石。
⚙️ Binder的四大核心组件
Binder通信架构基于C/S模式,由以下四个核心组件构成:
-
Client :服务的消费者。它不直接与服务端交互,而是通过一个"代理"向服务发起请求。
-
Server :服务的提供者。它负责实现具体的功能,并等待处理来自客户端的请求。
-
ServiceManager :一个"DNS服务器",即服务管理器。它负责管理系统中的所有服务,Server将服务注册到这里,Client通过查询它来找到所需的服务。
-
Binder Driver :整个Binder机制的"中枢神经",运行于Linux内核空间中。它负责承载所有核心功能:
- 数据中转和路由
- 建立服务注册和查找
- 身份校验(通过UID/PID保障安全)
- 线程池管理 和引用计数维护
🧭 一次完整的Binder通信流程
一次典型的Binder调用,从服务注册到最终调用返回,主要包括以下步骤:
sequenceDiagram
participant Server
participant ServiceManager
participant BinderDriver as Binder驱动
participant Client
Note over Server,ServiceManager: 1. 服务注册
Server->>ServiceManager: 注册服务 (addService)
ServiceManager->>BinderDriver:
Note over Client,ServiceManager: 2. 获取服务
Client->>ServiceManager: 获取服务 (getService)
ServiceManager->>Client: 返回服务代理 (Proxy)
Note over Client,BinderDriver: 3. 发起请求
Client->>BinderDriver: 发送请求 (BC_TRANSACTION)
BinderDriver->>Client: 确认收到 (BR_TRANSACTION_COMPLETE)
Note over BinderDriver,Server: 4. 转发与处理
BinderDriver->>Server: 转发请求 (BR_TRANSACTION)
Server->>Server: 处理请求
Note over Server,BinderDriver: 5. 返回结果
Server->>BinderDriver: 发送结果 (BC_REPLY)
BinderDriver->>Server: 确认收到 (BR_TRANSACTION_COMPLETE)
Note over BinderDriver,Client: 6. 结果返回
BinderDriver->>Client: 返回结果 (BR_REPLY)
| 步骤 | 描述 | 关键指令交互 | 核心说明 |
|---|---|---|---|
| 1. 服务注册 | Server启动后,将自己或自己提供的服务注册到ServiceManager中。 |
addService() |
只有系统服务有权限向ServiceManager注册,保证了安全性。 |
| 2. 获取服务 | Client向ServiceManager查询所需的服务,获得一个指向该服务的 "代理"(Proxy)。 |
getService() |
ServiceManager本身也是一个Server,同时也作为服务查找中心。 |
| 3. 发起请求 | Client通过代理对象发起调用,将方法调用及其参数封装成一个Parcel对象,并向Binder驱动发送BC_TRANSACTION指令。 |
BC_TRANSACTION | 封装数据的过程是在用户态完成的。 |
| 4. 内核处理 | Binder驱动完成数据拷贝的核心工作。它收到BC_TRANSACTION指令后,会向Client发送BR_TRANSACTION_COMPLETE回执,告知请求已收到。 |
数据拷贝 & BR_TRANSACTION_COMPLETE |
BR_TRANSACTION_COMPLETE只代表驱动收到数据,不代表Server已处理完成。 |
| 5. 转发与处理 | 驱动将请求转换为BR_TRANSACTION指令,并唤醒Server进程的空闲Binder线程来处理该请求。 |
BR_TRANSACTION | Binder线程池是高效处理并发的关键。 |
| 6. 结果返回 | Server处理完毕后,将结果封装好,向驱动发送BC_REPLY指令。驱动收到后返回BR_TRANSACTION_COMPLETE确认,并将结果转换为BR_REPLY指令发送给Client,唤醒之前阻塞的Client线程。 |
BC_REPLY → BR_REPLY | 整个过程会经历多次"等待"和"唤醒",但数据拷贝只有一次。 |
🗂️ 核心角色:什么是"代理" (Proxy)?
为什么Client能像调用本地对象一样调用Server的方法?这就是"代理模式"的作用:
- 对于Client :它拿到的是
BpBinder代理对象,这个对象就像是远程服务在本地的一个"替身",拥有和目标Server一模一样的方法。Client调用这些方法时,感觉和调用普通函数一样。 - 实际工作 :代理对象的所有方法都不会真正执行计算,而是将方法名和参数打包,通过Binder驱动传递给真正的Server去执行。
💡 高性能的关键:一次内存拷贝 & 异步处理
Binder的高性能源于其一次数据拷贝 和灵活的同步/异步处理模型。
🚀 一次数据拷贝 (One Copy)
- 传统IPC方式(如Socket)需要两次数据拷贝(用户空间→内核空间→目标用户空间)。
- Binder方式 :Server启动时,通过
mmap()将内核的一块内存区域映射到自己的用户空间。当Client要发送数据时,数据只需从Client空间拷贝到这块内核缓冲区 一次,Server就能因内存映射而直接访问 。这实现了一次拷贝,零次复制的效果。
⚡ 同步与异步事务
Binder支持两种事务类型,对应开发者熟悉的同步调用和异步调用:
- 同步事务 (Synchronous) :对应AIDL中没有
oneway关键字的方法。Client调用后会一直阻塞,直到Server处理完并返回结果。 - 异步事务 (Asynchronous) :对应AIDL中标记了
oneway的方法。Client调用后立即返回,不等待结果,适用于通知等场景。
🧵 Binder线程池的力量
为了提高并发处理能力,Binder引入了线程池:
- 每个希望接收Binder请求的进程,都会启动一个Binder线程池。
- 线程池在进程启动时创建,默认最大线程数为16。
- 当大量请求同时到达时,线程池会唤醒空闲线程并行处理。若所有线程繁忙,新请求会在驱动层排队等待。