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 的性能与安全问题。
Binder 在 Android 系统中的层级定位 应用层 (Application Layer) ServiceManager / AMS / WMS / 应用进程间 Binder 调用 框架层 (Framework Layer) IBinder / Binder / BinderProxy (Java) — AIDL 接口定义 Native 层 (C++ Runtime) libbinder / ProcessState / IPCThreadState / BpBinder / BBinder 内核层 (Kernel Layer) binder_driver / /dev/binder / 内存映射 / 线程管理 / 引用计数 Binder 贯穿 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 在内核与接收方用户态之间建立共享映射,发送方数据只需拷贝到内核缓冲区一次,接收方即可直接读取。
Binder 与 Socket 数据拷贝流程对比 Socket (2次拷贝) 发送方 用户态 接收方 用户态 内核 Socket 缓冲区 拷贝① 拷贝② Binder (1次拷贝) 发送方 用户态 接收方 用户态 内核 Binder 缓冲区 mmap 映射 仅 1 次拷贝 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调用流程

  1. 服务注册:Server 进程向 ServiceManager 注册服务(如 "activity"),ServiceManager 记录其 Binder 引用。
  2. 服务获取:Client 进程向 ServiceManager 查询服务名称,获得目标服务的 Binder 代理。
  3. 方法调用:Client 通过代理发起 transact() 调用,数据打包为 Parcel 后写入 Binder 驱动。
  4. 驱动转发:Binder 驱动根据目标句柄找到 Server 进程的 Binder 实体,将数据拷贝到 Server 的 mmap 缓冲区。
  5. 请求处理:Server 的 Binder 线程池从驱动读取请求,调用对应方法,将结果写回驱动。
  6. 结果返回:驱动将结果拷贝到 Client 的缓冲区,Client 线程被唤醒,读取返回数据。
性能陷阱: 每次 Binder 调用都涉及用户态→内核态→用户态的上下文切换。高频小数据量调用(如频繁读取系统属性)会导致显著的上下文切换开销,这是后续优化章节的重点关注对象。
Binder C/S 架构模型与调用流程 Client 进程 BpBinder (代理) 发起 transact() ServiceManager 服务注册/发现 名称→引用映射 Server 进程 BBinder (实体) 处理请求 Binder Driver (内核) 数据拷贝 / 线程调度 / 安全校验 / 引用计数 ① 注册服务 ② 获取服务 ③ transact() ④ 转发请求 ⑤ 返回结果 ⑥ 唤醒 Binder C/S 模型的关键设计: • ServiceManager 作为服务注册中心,解耦了 Client 与 Server 的直接依赖 • Binder 驱动承担数据中转与调度,Client 和 Server 无需关心底层传输细节 • 所有 IPC 调用均经过内核驱动,天然支持安全校验与权限管控

1.4 小结:Binder的设计哲学

Binder 并非追求“绝对最快”的 IPC,而是在 性能、安全、易用性 三者之间取得了最佳平衡:

  • 性能:1 次拷贝 + mmap 映射,远优于 Socket 的 2 次拷贝;同步调用模型简单高效。
  • 安全:内核级 UID/PID 校验,每个 Binder 调用都携带身份信息,无需应用层额外处理。
  • 易用性:面向对象接口设计,AIDL 自动生成桩代码,开发者只需关注业务逻辑。