Binder 驱动框架设计与分析

56 阅读3分钟

​Binder 是 Android 的核心通信机制​​,你可以把它想象成一个「快递系统」,让不同 App(进程)之间能安全高效地传递数据和调用功能。

1. 快递系统的三大角色

  • ​Client(客户)​​:想调用别人功能的程序。
  • ​Server(服务端)​​:提供功能的程序(比如获取 GPS)。
  • ​ServiceManager(快递总站)​​:管理所有服务的“电话簿”,服务需要先在这里注册,客户才能查询到。

举个例子:外卖 App(Client)想调用地图服务(Server)时,需要先问 ServiceManager:“地图服务在哪?”拿到地址后才能下单。


2. 跨进程快递的秘密(IPC)

不同 App 的内存是隔离的,就像两个平行世界。Binder 的解决方法是:

  1. ​内核做中转站​​:所有快递先送到内核(系统核心区),这里是所有进程共享的。
  2. ​减少搬运次数​​:通过 mmap 映射内存,让客户和内核共用同一块内存,数据只需复制一次,速度更快。

这就像两家公司共用同一个仓库,货物直接放进去就能被对方取走,不用来回搬运。


3. 远程调用功能(RPC)

Client 调用 Server 的函数就像本地调用一样简单,背后 Binder 帮我们:

  1. ​打包数据​​:写明“发给谁(Handle)”、“调哪个函数(Code)”、“参数是什么”。
  2. ​内核传递​​:通过快递系统(IPC)送到 Server。
  3. ​执行返回​​: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 找到其他服务

  1. ​服务注册​​:地图服务向 ServiceManager 注册,内核生成它的身份证(binder_node),并分配一个编号(desc)。
  2. ​客户查询​​:Client 问 ServiceManager 要地图服务的编号,内核生成一个引用(binder_ref)给 Client。
  3. ​发起调用​​:Client 用这个编号发送请求,内核通过引用找到对应的服务,完成调用。

这就像 ServiceManager 是黄页电话簿,客户查到编号后,就能直接拨打分机号联系目标服务。


总结

Binder 通过​​内核中转​​、​​内存映射​​和​​层级引用​​,实现了高效安全的跨进程通信。ServiceManager 作为服务管家,Client 和 Server 无需知道彼此细节,像本地调用一样简单。这种设计是 Android 系统流畅运行的基石之一。