Binder 是 Android 的核心通信机制,你可以把它想象成一个「快递系统」,让不同 App(进程)之间能安全高效地传递数据和调用功能。
1. 快递系统的三大角色
- Client(客户):想调用别人功能的程序。
- Server(服务端):提供功能的程序(比如获取 GPS)。
- ServiceManager(快递总站):管理所有服务的“电话簿”,服务需要先在这里注册,客户才能查询到。
举个例子:外卖 App(Client)想调用地图服务(Server)时,需要先问 ServiceManager:“地图服务在哪?”拿到地址后才能下单。
2. 跨进程快递的秘密(IPC)
不同 App 的内存是隔离的,就像两个平行世界。Binder 的解决方法是:
- 内核做中转站:所有快递先送到内核(系统核心区),这里是所有进程共享的。
- 减少搬运次数:通过
mmap映射内存,让客户和内核共用同一块内存,数据只需复制一次,速度更快。
这就像两家公司共用同一个仓库,货物直接放进去就能被对方取走,不用来回搬运。
3. 远程调用功能(RPC)
Client 调用 Server 的函数就像本地调用一样简单,背后 Binder 帮我们:
- 打包数据:写明“发给谁(Handle)”、“调哪个函数(Code)”、“参数是什么”。
- 内核传递:通过快递系统(IPC)送到 Server。
- 执行返回:Server 执行函数后,结果按原路返回。
例如:Client 调用“获取位置”函数,内核把请求传给地图服务,拿到位置后再回传给 Client。
4. 快递系统的核心地图(内核结构)
- binder_node(服务身份证):每个服务在内核中的唯一标识。
- binder_proc(进程档案):记录一个 App 的所有服务和引用。
- binder_ref(服务地址):其他 App 通过这个“引用”找到目标服务。
关系:Client 的引用(binder_ref)→ 服务的身份证(binder_node)→ 服务所在的 App(binder_proc)。
5. 如何找到目标服务?
5.1 找到 ServiceManager
- ServiceManager 是全局唯一的,内核会直接标记它的位置,所有 App 都知道怎么找它。
5.2 找到其他服务
- 服务注册:地图服务向 ServiceManager 注册,内核生成它的身份证(binder_node),并分配一个编号(desc)。
- 客户查询:Client 问 ServiceManager 要地图服务的编号,内核生成一个引用(binder_ref)给 Client。
- 发起调用:Client 用这个编号发送请求,内核通过引用找到对应的服务,完成调用。
这就像 ServiceManager 是黄页电话簿,客户查到编号后,就能直接拨打分机号联系目标服务。
总结
Binder 通过内核中转、内存映射和层级引用,实现了高效安全的跨进程通信。ServiceManager 作为服务管家,Client 和 Server 无需知道彼此细节,像本地调用一样简单。这种设计是 Android 系统流畅运行的基石之一。