为什么要造轮子-Binder
先看Linux系统默认为我们提供了哪些进程通信机制:
IPC 即 Inter-Process Communication (进程间通信)
1、管道
通过内核空间建立管道,进行跨进程通信
2、共享内存
共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU可以在各个进程访问到这片内存。
3、文件
通过将数据写入到一个文件中,不同进程可以对这个文件进行读取访问,来达到跨进程通信目的。 不过,多进程同时访问一个文件,存在并发和IO性能低的问题
4、Socket
Android 进阶:进程通信之 Socket (启本地服务进行连接)
Linux跨进程通信对比
通信方式 | 性能 | 安全 | 模型 |
---|---|---|---|
管道 | 性能低,跨进程通信需拷贝2次数据 | 安全 | 1v1 |
共享内存 | 性能最高,不需要拷贝数据 | 数据不安全,多线程比较难控制 | NvN |
Socket | 性能最低,2次拷贝,用户和内核的CPU状态切换 | 安全 | NvN |
文件共享 | 性能低,2次拷贝 | 不安全 | NvN |
有没有性能更好拷贝一次和安全的跨进程通信?
Binder
- 性能:拷贝一次数据,但数据大小限制=1M-8k
- 安全:为每个APP分配UID,同时支持实名和匿名
- NvN
相关机制
Binder Server会专门建二段用于binder通信的虚拟内存区间,一段在内核态,一段在用户空间。这两段虚拟地址空间映射到同样的物理地址上,当有数据拷贝到Binder Server的内核态地址空间,实际上用户态也就可以直接访问了。当Binder client要把一个数据块拷贝(调用系统copy_from_user()从用户空间copy到内核空间)到binder server(通过binder transaction)的时候,实际上会在binder server的内核虚拟地址空间中分配一块内存,并把binder client的用户地址空间的数据拷贝到binder server的内核空间。因为binder server的binder内存区域被同时映射到用户空间和内核空间,因此就可以省略一次数据考虑,提高了性能。
Binder使用场景对比
并不是实现了IBinder接口就是跨进程通信,在Stub#asInterface(android.os.IBinder obj)中android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR)有判断是否为同一进程,在同一进程会用进程内部通信。
- Intent
组件Intent进程跳转,比较常用调用就不说了。 - Messenger
Android 进阶:进程通信之 Messenger 使用与解析 - AIDL
Android 进阶:进程通信之 AIDL 的使用
1、定义进程A的Activity
2、定义进程B的Server
3、根据需求接口定义AIDL接口
4、activity和server进行绑定并通过aidl接口进行通信
Android 进阶:进程通信之 Binder 机制浅析
Android 进阶:进程通信之 AIDL 解析
- ContentProvider
Android 进阶:进程通信之 ContentProvider 内容提供者
通信方式 | 优点 | 缺点 | 使用场景 |
---|---|---|---|
Intent | 简单易用 | 只能传输Bundle支持的数据类型 | 四大组件的进程通信,Activity,Broadcast |
AIDL | 功能强大,支持一对多的并发通信,支持实时通信 | 使用稍复杂,需要处理好线程同步 | 一对多通信且有RPC需求 |
Message | 功能一般,支持一对多的串行通信,支持一对多并发数据共享 | 不能很好处理并发现象,只能传输Bundle支持的数据类型 | 低并发的一对多即时通信 |
ContentProvider | 数据访问方面功能强大,支持一对多并发数据共享 | 受约束的AIDL,主要提供数据源的CRUD操作 | 一对多的进程间的数据共享 |
Binder 通信机制
Binder四层通信协议
-
按进程通信
从进程角度看,参与Binder通信的实体有三个:Client、 Server和ServiceManager。Server中的service组件对外提供了服务,但是需要对外公布,因此它会向ServiceManager注册自己的服务。Client想要请求服务的时候统一到ServiceManager去查询,获取了对应的描述符后即可以通过该描述符和Service组件进行通信。当然,这些IPC通信并不是直接在Client、Server和ServiceManager之间进行的,而都是需要通过Binder Driver间接完成。
image.png -
Binder 机制跨进程通信流程
image.png
再细分
image.png
- BpBinder和BBinder
BpBinder和BBinder在Native IPC层,
BpBinder 发送消息给Service对象,并处理相关事件。
BBinder 接受Client发送信息,并处理事件。