Binder属于Android特有的IPC机制,仅支持Android内部进程间通讯,因其性能高,接口化特性被大量应用于Android中。下面是各IPC的性能对比:
IPC方式 | 数据拷贝次数 | 同步请求 | 异步请求 | 请求超时 | 跨平台 | 跨主机 | 安全策略 |
Binder | 1 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 支持 |
Socket/管道/消息队列 | 2 | 支持 | 支持 | 支持 | 支持 | 支持 | 不支持(依赖上层协议) |
共享内存 | 0 | 不支持 | 不支持 | 不支持 | 支持 | 支持 | 不支持 |
DBus | 4 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
Binder优势和实现原理
Binder的优势:
性能强、稳定性高、安全性高
优势 | 描述 |
性能 | 只需要一次拷贝,性能上仅次于共享内存 |
稳定性 | 基于C/S架构,职责明确,架构清晰 |
安全性 | 为每个APP分配UID,进程的UID是鉴别进程身份的重要标志 |
一次完整的Binder IPC通信过程:
首先 Binder 驱动在内核空间创建一个数据接收缓存区
接着在内核空间开辟一块内核缓存区,通过内存映射机制 ( mmap ) 建立 内核缓存区 和 内核中数据接收缓存区 之间的映射关系,以及 内核中数据接收缓存区 和 接收进程用户空间地址 的映射关系
发送方进程通过系统调用 copy_from_user () 将数据拷贝到内核中的 内核缓存区 ,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间
Binder实现:
Binder架构也是采用分层架构设计, 每一层都有其不同的功能
Binder的实现框架见右图,大致的binder通讯过程:
一个进程使用 BINDERSETCONTEXT_MGR 命令通过 Binder 驱动将自己注册成为 ServiceManager
Server 通过驱动向 ServiceManager 中注册 Binder ( Server 中的 Binder 实体),表明可以对外提供服务。驱动为这个 Binder 创建位于内核中的实体节点以及 ServiceManager 对实体的引用,将名字以及新建的引用打包传给 ServiceManager , ServiceManger 将其填入查找表
Client 通过名字,在 Binder 驱动的帮助下从 ServiceManager 中获取到对 Binder 实体的 Proxy 引用对象,通过这个引用对象就能实现和 Server 进程的通信
匿名Binder
匿名binder就是没有向servicemanager提交注册的binder。匿名binder必须是建立在一个实名binder之上的,实名binder就是在service manager中注册过的。首先client和server通过实名binder建立联系,然后把匿名binder通过这个实名通道“传递过去”,对方也可以正确获取service的代理对象Bpxxx