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