Android binder(RPC) 通信概念与架构

发布时间:2026/6/29 17:02:31
Android binder(RPC) 通信概念与架构 文章目录一、preface1、资料快车2、概述1.1 Binder与其它 IPC 的效率对比1.2 区分RPC与IPC1.3 三大 binder 域Treble 后1.4 mmap内存技术3、基础概念二、Binder框架图1、对等通信2、binder三大角色3、Binder各层级关键类![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e1e2b2a664884d5bad8797bab653af3d.png)4、AIDL/HIDL binder5、通信架构图三、Binder 基础模型3.1 Binder 全栈架构图应用 → framework → native → libbinder → 内核3.2 核心概念3.3 引用计数强/弱3.4 BC / BR 协议四、源码目录4.1 内核侧4.2 用户态一、preface1、资料快车1、Framework篇 - 彻底理解Binder通信架构https://blog.csdn.net/u014294681/article/details/880940882、Framework-进程间通信之Binder机制AIDLhttps://blog.csdn.net/blankmargin/article/details/1267875253、Framework源码Binder驱动解析https://zhuanlan.zhihu.com/p/5420587024、Framework层的Binder源码分析篇https://www.zhihu.com/tardis/zm/art/554115552?source_id10055、书籍 - Android系统源代码情景分析6、AIDL的使用详解APPhttps://blog.csdn.net/u014294681/article/details/881269882、概述Binder是 Android 的核心 IPC/RPC 机制几乎承载了 Android 所有的跨进程通信应用与系统服务、系统服务之间、HAL 与框架、甚至dumpsys、service list都建立在它之上。理解 Binder 是理解 Android 整个系统框架的前提。本平台RK3568 Android 11的 Binder 实现是纯 AOSP 内核栈drivers/android/binder.c约 6187 行RK 没有对其做功能性改动——唯一的平台相关点是rockchip_defconfig打开了CONFIG_ANDROID_BINDERFSy三个设备节点/dev/binder、/dev/hwbinder、/dev/vndbinder由 binderfs 创建并通过 init.rc 建立符号链接。1binder在哪里使用发生在用户态的各个层级-- APP/framework/native/JNI/driver2使用的形式 – aidl/hidl无论是java/c都是getserver(client/Stub.proxy) / addserver(server/stub) 形式3我们应该关注最顶层的实现底层是恒定不变只要简单识别即可且工具已经帮我们实现封装这里为什么不用代码来封装工具如此不直观纯写代码仍然有一定工作量并且都是重复代码工具可以让我们集中精力定义和实现接口3binder系统的复杂之处在于上层的层层复杂封装1.1 Binder与其它 IPC 的效率对比Android 几乎所有跨进程通信都走 Binder而非 Linux 原生的 pipe/socket/共享内存/消息队列。原因不只是快而是效率、安全、易用三者的综合最优。1数据拷贝次数对比核心IPC 方式内核拷贝次数说明共享内存shm/mmap0零拷贝但需自加锁、无内核仲裁安全隐患大Binder1mmap把接收方地址映射进内核发送方copy_from_user一次即达pipe / FIFO2copy_from_user发送方 copy_to_user接收方UNIX socket2同上消息队列msgget2同上信号0只能传一个信号编号不能传数据Binder 的关键接收进程在open(/dev/binder)后mmapPROT_READ一段空间内核在该进程页表里建立内核页 ↔ 用户页同一物理页映射vm_insert_page。一次 transaction 时内核把发送方数据copy_from_user进这个内核页接收进程用户态直接读到——省掉了传统 IPC 的第二次copy_to_user。2综合能力对比维度BinderSocket共享内存pipe/FIFO消息队列信号D-Bus拷贝次数12022—2CS / 面向对象✅△✗△△✗✅内核安全仲裁✅ SELinux✗✗✗✗✗△用户态死亡通知✅✗✗✗✗✗✗强/弱引用计数✅✗✗✗✗✗✗fd/对象传递✅△✗✗✗✗✗跨域策略Treble 三域✅✗✗✗✗✗△3为何 Binder “更高效”——不只是少一次拷贝一次拷贝核心对中小消息 mmap 上限单端默认 1MB−2页相比 socket/pipe 的两次拷贝减少约一半内核态拷贝开销相比共享内存仅多一次拷贝却换来内核仲裁与安全。面向对象 引用计数通信单元是对象引用binder node → handle一次getService拿到 handle 后续调用复用不必每次编解码地址/连接强/弱引用 死亡通知让对象生命周期与进程解耦无需应用层心跳。线程池 优先级继承服务端单进程多 binder 线程默认 15应对高并发场景驱动按需BR_SPAWN_LOOPER扩容同步调用时发送方优先级继承到服务端线程binder_transaction_priority保证 UI 线程发起的调用能及时在服务端响应避免优先级反转。内核内同步语义同步 transaction 天然阻塞发送方等BR_REPLY省去应用层等待/超时协议oneway 则零等待异步投递node 级串行化。fd/对象直传flat_binder_object的BINDER_TYPE_FD在内核里直接binder_alloc_fd把 fd 转移到目标进程如 Surface/ashmem 句柄无需序列化文件路径。统一服务管理 安全模型servicemanager 提供按名字寻址SELinux 在security_binder_transaction处对每次调用做谁能调谁判定集中可控socket/shm 要应用自行实现鉴权。一句话共享内存最快但不安全也不好用socket/pipe 通用但慢且无对象语义。Binder 用一次内核拷贝 内核仲裁 面向对象引用在足够快和安全/易用之间取得 Android 需要的平衡——这是它取代传统 IPC 的根本原因。1.2 区分RPC与IPC1、RPC和IPC IPCInter-process communication 进程间通信只搬数据RPCRemote Procedure call远程过程调用在 IPC 之上再封装调用哪个对象、哪个方法、什么参数、什么返回值。Binder 底层是 IPC一次 transaction 搬一个 binder_transaction_data但 libbinder/AIDL 层把它包装成了 RPC——transact(handle, code, data, reply) 2、RPC四要素 handle : 调用哪个服务 code : 调用哪个接口 data : 入参数据 reply : 出参数据1.3 三大 binder 域Treble 后设备域库context manager用途/dev/binderframeworklibbinderservicemanager应用/框架进程 ↔ 框架系统服务/dev/hwbinderhwbinderlibhwbinderhwservicemanagerHIDL HALTreble 前风格/dev/vndbindervendorlibbinder(VNDK)vndservicemanagervendor 进程间三者是三个独立的binder_device各持一个独立的binder_context独立的 context manager 节点互不可见。libbinder 在 VNDK 编译时__ANDROID_VNDK__默认打开/dev/vndbinder。1.4 mmap内存技术本质上就是 开辟一个特区内容空间 - 不区分用户空间和内核空间用户态和内核态都可以畅通访问3、基础概念1、Bn/Bp Bn (binder native) - CPP服务端implement BB (Base binder) - native服务端 Bp (binder proxy) - 客户端 2、RPC/IPC IPC : Inter-process commuication RPC : Remote Procedure call - 在IPC基础上再封装一层 3. AIDL : Android interface Defintion Language ,Android 接口定义语言用于应用层进程间通信IPC, Service与客户端跨进程调用(双向通信) HIDL : HAL interface Definition Language HAL 接口定义语言 4、 defer : 延迟 5、shrinker -Linux内核的内存回收机制 shrinker - 内存收缩器 LRU - last Recently Used 最近最少使用 reclaim - 释放不活跃的内存 kswapd - 内核交换守护进程二、Binder框架图1、对等通信122、binder三大角色3、Binder各层级关键类4、AIDL/HIDL binder1https://blog.csdn.net/yangwen123/article/details/798361092普通Binder架构在这里插入图片描述3HIDL Binder架构5、通信架构图1通信架构图2关键代码流程客户端调用 getService App 进程 │ ▼ BpServiceManager::getService(name) │ ▼ BpRefBase::remote() → BpBinder(handle0) │ ▼ BpBinder::transact(GET_SERVICE, data, reply) │ ▼ IPCThreadState::transact(handle0, GET_SERVICE, ...) │ ▼ ioctl(BINDER_WRITE_READ) ──────→ Binder Driver │ ▼ 查找 handle0 对应的进程 │ ▼ System Server 进程 │ ▼ BBinder::onTransact(GET_SERVICE, ...) │ ▼ BnServiceManager::onTransact(GET_SERVICE, ...) │ ▼ ServiceManager::getService(name) // 本地实现 │ ▼ 返回结果 ←─────── IPCThreadState ──────── Binder Driver │ ▼ 客户端收到 reply三、Binder 基础模型3.1 Binder 全栈架构图应用 → framework → native → libbinder → 内核自上而下五层每层标注该层的关键技术客户端调用沿箭头下沉到内核内核一次拷贝 跨进程投递到服务端服务端onTransact自下而上执行。右列是各层对应的源码位置。应用层 App / Java · Kotlin ┌───────────────────────────────────────────────────────────────────┐ │ • AIDL 接口 • Stub.Proxy(客户端 Bp) / Stub(服务端 Bn) │ app/src/**/aidl │ • ServiceConnection.bindService • IBinder / Binder.java │ android.os.* │ • ServiceManager.getService / addService系统服务 │ └───────────────────────────────────────────────────────────────────┘ │ JNIandroid_util_Binder.cppJava ↔ native ▼ Framework 层 frameworks/baseJava ┌───────────────────────────────────────────────────────────────────┐ │ • android.os.Binder服务端/ BinderProxy客户端代理 │ frameworks/base/core/java/android/os │ • android.os.Parcel(Java) • IServiceManager.aidl │ └───────────────────────────────────────────────────────────────────┘ │ Parcel 跨 JNI 下沉到 C ▼ Native / C 层 libbinder ┌───────────────────────────────────────────────────────────────────┐ │ • BpBinder(handle, transact) ── 客户端代理 │ libs/binder/BpBinder.cpp │ • BBinder(onTransact) ── 服务端桩 │ libs/binder/Binder.cpp │ • IInterface / asInterface() / DECLARE_META_INTERFACE │ libs/binder/IInterface.h │ • IServiceManager defaultServiceManager() • Parcel(C) │ libs/binder/IServiceManager.cpp │ • AIDL 生成的 BnXXX/BpXXX 即此层HIDL → libhwbinder │ └───────────────────────────────────────────────────────────────────┘ │ transact → writeTransactionData(BC_TRANSACTION) ▼ libbinder 运行时 frameworks/native/libs/binder ┌───────────────────────────────────────────────────────────────────┐ │ • ProcessState::self() open(/dev/binder) mmap(PROT_READ) │ libs/binder/ProcessState.cpp │ setThreadPoolMaxThreadCount默认 15 │ │ • IPCThreadState::self() talkWithDriver → ioctl(BINDER_WRITE_READ) │ libs/binder/IPCThreadState.cpp │ BC/BR 主循环 executeCommand(BR_*) │ │ joinThreadPool(BC_ENTER/REGISTER_LOOPER) │ └───────────────────────────────────────────────────────────────────┘ │ ioctl(/dev/binder, BINDER_WRITE_READ, {BC_TRANSACTION, …}) ▼ 内核 binder 驱动 drivers/android/binder.c~6200 行 ┌───────────────────────────────────────────────────────────────────┐ │ • 数据结构binder_proc / thread / node / ref / buffer / txn │ binder.c / binder_alloc.c │ • binder_transaction() handle → ref → node → target_proc │ │ ① security_binder_transaction SELinux 仲裁 │ │ ② binder_alloc_new_buf 在 target mmap 空间分配 buffer│ │ ③ ★ 一次拷贝 copy_from_user 发送方 → target buffer │ │ ④ fixup flat_binder_object binder↔handle / fd 转移 │ │ ⑤ 入 target todo 唤醒线程 → 对端 BR_TRANSACTION │ │ • 引用计数(强/弱) • 死亡通知 • 优先级继承 • BR_SPAWN_LOOPER 线程池 │ ├───────────────────────────────────────────────────────────────────┤ │ • binderfs /dev/binder /dev/hwbinder /dev/vndbinder │ binderfs.c │ 三域 三个独立 binder_context / context managerTreble 隔离 │ └───────────────────────────────────────────────────────────────────┘读图五层从上到下封装厚度递减应用层最厚AIDL 自动生成 Stub/Proxy开发者只写接口libbinder 运行时最薄直接 ioctl内核是真正的搬运工。下沉路径客户端foo.方法()→ Stub.Proxytransact→ JNI →BpBinder::transact→IPCThreadState::transact写BC_TRANSACTION→ioctl(BINDER_WRITE_READ)。每一层只做一件事上层打包参数下层搬数据。跨进程在内核发生客户端到内核是普通ioctl内核binder_transaction把数据一次拷贝进服务端 mmap 空间、唤醒服务端线程——服务端进程这才参与BR_TRANSACTION→BBinder::onTransact→ 业务全程对应用透明。三大域图中/dev/binder|hwbinder|vndbinder是三个独立 binderfs 设备物理隔离 framework/hw/vendor 三套服务空间见 1.3。本图是分层栈视角1.3 是同一条链路的调用时序视角Client/Server/Driver 三列两者互补。对照显示侧libbinder 之于 binder ≈ libdrm 之于 DRMAIDL 之于 libbinder ≈ “驱动自动生成胶水”详见 Linux DRM 文档。3.2 核心概念概念说明binder node内核中代表一个可被跨进程调用的对象。服务端BBinder首次传递给驱动时创建挂在binder_proc-nodes按ptr排序的红黑树。binder ref客户端对某个 node 的句柄引用。binder_ref-data.desc即用户态看到的 handle0 表示 context manager。同一进程对同一 node 只有一个 ref。handle用户态的 32 位引用号。handle0特指 servicemanagercontext manager node。binder_buffer在接收进程 mmap 空间里切出的一段缓冲承载一次 transaction 的数据。用完由用户态BC_FREE_BUFFER归还。binder_proc / binder_thread一个打开/dev/binder的进程 / 一个 binder 线程。flat_binder_objectParcel 中对象的扁平表示——把一个强/弱 binder、handle、fd 等塞进数据流驱动在 transaction 时改写它binder↔handle 翻译、fd 转移。3.3 引用计数强/弱binder node 同时被内核internal_strong_refs和用户态local_strong_refs引用强弱两套独立计数。用户态通过BC_ACQUIRE/RELEASE/INCREFS/DECREFS显式增减驱动在 transaction 期间临时增持完成后归还。当强引用归零且无弱引用时node 被释放客户端在此之前用BC_REQUEST_DEATH_NOTIFICATION注册的死亡通知会以BR_DEAD_BINDER投递。3.4 BC / BR 协议BC_Binder Command用户态→驱动写在binder_write_read.write_buffer。如BC_TRANSACTION、BC_REPLY、BC_ACQUIRE、BC_ENTER_LOOPER、BC_FREE_BUFFER、BC_REQUEST_DEATH_NOTIFICATION。BR_Binder Return驱动→用户态读自read_buffer。如BR_TRANSACTION、BR_REPLY、BR_TRANSACTION_COMPLETE、BR_DEAD_REPLY、BR_SPAWN_LOOPER、BR_NOOP。一次ioctl(BINDER_WRITE_READ)同时携带一批 BC 与读出一批 BR。四、源码目录4.1 内核侧1.源码 kernel/drivers/android/* 2.UAPI 1kernel/include/uapi/linux/android/binder.h542 行所有 ioctl 号、BC/BR、flat_binder_object 等 2kernel/include/uapi/linux/android/binderfs.h文件行数角色binder.c6187核心驱动open/mmap/ioctl、transaction、node/ref/thread 管理、debugfsbinder_alloc.c1244每进程 buffer 分配器 一次拷贝页管理LRU/shrinkerbinder_alloc.h187struct binder_alloc/binder_buffer/binder_lru_pagebinderfs.c~770per-namespace 伪文件系统动态创建 binder 设备节点 binder-controlbinder_internal.h146binder_context/binder_device、transaction-log、debug seq_file 声明binder_trace.h~415ftracebinder类别所有TRACE_EVENT4.2 用户态层路径说明libbinderframeworks/native/libs/binder/通用 Binder IPC用于应用与系统服务System Server、应用之间等的常规进程间通信关键类ProcessState、IPCThreadState、BpBinder、BBinder、IServiceManager、Parcellibhwbindersystem/libhwbinder/硬件 Binder IPC专门用于 Android 框架Framework与硬件抽象层HAL 之间的通信servicemanagerframeworks/native/cmds/servicemanager/main.cpp/ServiceManager.cpp(BnServiceManager) /Access.cpp(SELinux ACL)hwservicemanagersystem/hwservicemanager硬件 Binder IPCaidl-gensystem/tools/aidl/将.aidl生成 BnXXX/BpXXXC/Java/NDKhidl-gensystem/tools/hidl/将.hal生成 HIDL 桩