前言
Android系统内核是Linux内核。Android中Binder作为进程间通信的核心机制。
Linux内核进程通信有
- 管道
- 内存共享
- Socket
- File
| 管道 | 效率低;两次拷贝;数据从应用A拷贝到内核管道中,管道再拷贝到应用B | 安全 | 1v 1 |
|---|---|---|---|
| 内存共享 | 效率高;不需要拷贝,A B C共享一块内存 | 不安全 | N v N |
| Socket | 效率低;两次拷贝;用户和CPU内核状态切换 | 安全 | C/S模型 |
| File | 文件操作 | 更不安全 | -- |
| Binder | 一次拷贝 | 安全:为每个应用分发UUID,通信时进行验证;支持实名和匿名 |
Binder的一次拷贝发生在用户空间拷贝到内核空间
- 用户空间:App进程与逆行的内存空间
- 内核空间:系统驱动 硬件相关的代码运行的内存空间,ID为0的进程运行的空间
- 程序局部性原则:只加载少量代码;应用没有运行的代码放在磁盘中,运行时高速缓冲区进行加载要运行的代码;默认一次加载一个页(4K),若不够4K就0补齐。
- MMU:内存管理单元;给CPU体哦那个虚拟地址;当变更操作赋值时:
- CPU拿着虚拟地址和值给到MMU
- MMU用虚拟地址匹配到物理地址,MMU区物理内存中进行赋值;
- 物理地址:物理内存的实际地址,并不是磁盘;
- 虚拟地址:MMU根据物理内存的实际地址翻译出的虚拟地址;提供给CPU使用
- 页命中:CPU读取变量时,MMU在物理内存的页表中找到了这个地址;
- 页未命中:CPU读取变量时,MMU在物理内存的页表中没有找到这个地址,此时会触发MMU去磁盘读取变量并存到物理内存中。
- 普通的二次拷贝:
-
- 应用A拷贝到服务端:coay_from_user
-
- 从服务端拷贝到应用B:coay_from_user
mmap():
- 在物理内存中开辟一段固定大小的内存空间
- 将磁盘文件与物理内存进行映射(绑定)
- MMU将物理内存转换为虚拟地址给CPU(虚拟地址映射物理内存)
Binder机制的核心概念
采用C/S(Client/Server)架构,包含Service端和Client端:
- Binder驱动层:是Binder核心,负责处理进程间通信的底层细节。通过/dev/binder设备提供服务,负责实现Binder通信基本机制。
- Binder服务端和客户端:服务端通过Binder注册自己的对象(Binder对象),客户端通过Binder获取服务端的引用
- Binder对象:是进程间通信的核心。当客户端需要调用服务端的方法时,实际上是通过Binder对象进行的。Binder对象包含了对应的服务方法以及Binder引用
- Binder引用计数:Binder采用引用技术机制管理对象的生命周期。当客户端获取服务端Binder引用时,引用计数增加;当客户端或服务端不再需要时,引用技术减少。当引用计数为0时,系统回收Binder对象。
工资流程:
- 注册服务:服务端将Binder对象注册到Binder驱动层
- 获取引用:客户端获取服务端Binder引用
- 调用方法:客户端通过Binder引用调用服务端的方法
- 数据传输:参数和返回值通过Binder进行序列化和反序列化传输
- 应用技术管理:管理Binder引用计数,确保对象在不再需要时能够被释放
Binder如何实现跨进程通信
Binder是Android系统中一种高效的进程间通信(IPC)机制,核心在于Binder驱动和Binder服务。当一个进程希望与另一个进程通信时,Binder会通过Binder驱动在进程间建立通信通道,实现数据传输。
1.Binder通信流程:
- Client端:发起Binder通信方。通过BinderProxy创建Binder对象,通过transact方法将数据发送到Binder驱动
- Binder驱动:位于内核空间,负责接收Client端的请求并将其传送给Server端,并调用onTransact方法处理请求。
2.跨进程通信
Binder驱动的作用:Binder驱动通过内核的共享内机制,将数据从一个进程复制到另一个进程,实现了进程间的数据传输。 Binder应用计数:Binder使用引用计数来管理对象的生命周期,确保在没有引用时可以及时释放资源
Binder和AIDL区别
Binder是Android的一种底层机制,AIDL是在Binder基础上提供的一种高级接口定义语言。AIDL简化了开发者进行IPC时操作,通过定义接口 数据类型 系统自动生成相应的Binder代码。 Binder是一种通用的进程间通信机制,而AIDL是一种对Binder的封装,提供更方便的开发方式。在使用AIDL时,开发者需要定义接口和数据类型,系统会帮助生成底层的Binder通信代码。
Binder生命周期管理
Binder引用计数:
- 增加引用计数:Binder对象被传递给其他进程,引用计数会增加。通过transact传递Binder对象,引用计数加一。
- 减少引用计数:Binder对象不再使用时,应用计数减少。通过unlinkToDeath解除Binder的死亡通知,计数减一。
Binder死亡通知:
- 设置死亡通知:通过linkToDeath方法,当Binder对象所在的进程终止时,会收到死亡的通知。
- 处理死亡通知:重写Binder.DeathRecipient接口,实现binderDied方法处理Binder对象所在进程的死亡情况。