Android Binder 跨进程通信机制
目录
Android Binder 跨进程通信机制
Binder 是 Android 系统中最核心、最独特的 IPC(Inter-Process Communication,跨进程通信)机制。可以说:无 Binder,不 Android。
理解 Binder 不能只把它当成一个"技术",而要把它看作一种架构设计。
1. 为什么需要 Binder
在 Linux 系统中,已经有了管道 (Pipe)、Socket、共享内存、信号量等 IPC 机制,为什么 Google 还要重新造一个轮子?
1.1 传统 IPC 的问题
| IPC 机制 | 数据拷贝次数 | 优点 | 缺点 |
|---|---|---|---|
| 管道 (Pipe) | 2 次 | 简单 | 单向、效率低 |
| Socket | 2 次 | 通用、可跨网络 | 效率低、开销大 |
| 共享内存 | 0 次 | 效率最高 | 同步复杂、不安全 |
| 信号量 | - | 同步原语 | 只能传信号 |
| Binder | 1 次 | 高效、安全、易用 | Android 特有 |
1.2 Binder 的优势
性能 (Performance):
- Socket 传输效率低(数据拷贝 2 次)
- 共享内存虽然快(拷贝 0 次)但管理复杂且不安全
- Binder 只需 1 次拷贝,完全满足移动端高频调用需求
安全 (Security):
- 传统 Linux IPC 对通信双方的身份校验较弱(通常依赖 UID/GID)
- Binder 机制支持实名制,内核层直接校验 UID/PID
- 适合权限分明的 Android App 沙箱模型
面向对象 (Object-Oriented):
- Android 的设计理念是组件化(Activity, Service)
- Binder 天然支持 RPC(远程过程调用)
- 跨进程调用函数就像调用本地对象的方法一样自然
2. Binder 架构:四要素
Binder 采用 C/S (Client-Server) 架构,包含四个关键角色:
| |
2.1 Client (客户端)
发起服务请求的进程。
| |
2.2 Server (服务端)
提供服务的进程。
| |
2.3 ServiceManager (服务注册中心)
作用:电话本 / DNS。
| |
流程:
- Server 启动后注册到 ServiceManager
- Client 想用服务时,先问 ServiceManager 要到 Server 的句柄
- Client 通过句柄与 Server 通信
2.4 Binder Driver (Binder 驱动)
位置:Linux 内核层 (/dev/binder)
作用:幕后英雄
- Client、Server、ServiceManager 都在用户空间,彼此不能直接访问内存
- 所有的数据传输、对象映射、线程管理,全靠内核里的驱动来搬运
| |
3. Binder 通信原理:一次拷贝
这是 Binder 最核心的技术亮点。
3.1 传统 IPC (如 Socket):两次拷贝
| |
3.2 Binder 机制:一次拷贝
| |
3.3 内存映射原理
| |
3.4 一次拷贝 vs 零次拷贝
| 方案 | 拷贝次数 | 优点 | 缺点 |
|---|---|---|---|
| 共享内存 | 0 次 | 效率最高 | 需要同步机制、不安全 |
| Binder | 1 次 | 安全、有驱动管理 | 效率略低于共享内存 |
| Socket | 2 次 | 通用 | 效率低 |
4. Binder 驱动详解
4.1 Binder 驱动入口
| |
4.2 ioctl 命令
| |
4.3 Binder 协议命令
| |
5. AIDL 与代码层实现
5.1 AIDL 文件定义
| |
5.2 生成的代码结构
| |
5.3 Parcel 数据序列化
| |
6. 实战示例代码
💡 思路一句话: Binder 是 Android 进程间通信的核心 — 理解 Binder 调用链(Client Proxy → Binder Driver → Server Stub)后,可以通过 hook Binder.transact 拦截和修改任意跨进程调用。
6.1 完整 AIDL 服务实现
以下是一个完整的自定义 Binder 服务示例,包含服务端、客户端和 AIDL 定义。
步骤 1:定义 AIDL 接口
| |
步骤 2:实现服务端
| |
步骤 3:AndroidManifest.xml 注册服务
| |
步骤 4:实现客户端
| |
6.2 Native Binder (C++) 示例
在 Native 层直接使用 Binder,不依赖 Java/Kotlin。
Server 端 (C++)
| |
| |
Client 端 (C++) - Proxy 实现
| |
6.3 ServiceManager 原理与实现
| |
6.4 Parcel 底层原理
| |
6.5 Binder 线程池管理
| |
7. Binder 通信流程图解
7.1 完整通信流程
| |
7.2 形象比喻
| |
7. Binder 在逆向中的应用
8.1 Hook Binder 调用
| |
8.2 监控系统服务调用
| |
8.3 分析 AIDL 接口
| |
8.4 Binder 数据解析
| |
8. 总结
8.1 Binder 核心要点
| 特性 | 说明 |
|---|---|
| 地位 | Android 的神经系统 |
| 架构 | C/S 架构:Client、Server、ServiceManager、Driver |
| 性能 | 1 次拷贝 (mmap 内存映射) |
| 安全 | 内核层 UID/PID 校验 |
| 易用 | AIDL 封装 RPC 调用 |
8.2 限制
- 传输大小限制:通常 1MB - 8KB,过大的图片不要通过 Binder 传
- 同步调用:Client 发起的调用通常是同步的,Server 耗时太久会导致 ANR
- Android 特有:不是标准 Linux IPC,只能在 Android 中使用
8.3 Binder 的重要性
理解了 Binder,你就理解了:
- 为什么 Android App 可以互相调起
- 为什么系统服务可以管理所有 App
- 插件化和组件化开发的底层基石
- LSPosed 等框架的跨进程通信机制
推荐下一步:
相关内容
如果这篇文章对你有帮助,请我喝杯咖啡吧~
支付宝
微信