Android Binder

169 阅读5分钟

前言

Android系统内核是Linux内核。Android中Binder作为进程间通信的核心机制。

Linux内核进程通信有

  1. 管道
  2. 内存共享
  3. Socket
  4. 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补齐。
  1. 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对象。

工资流程:

  1. 注册服务:服务端将Binder对象注册到Binder驱动层
  2. 获取引用:客户端获取服务端Binder引用
  3. 调用方法:客户端通过Binder引用调用服务端的方法
  4. 数据传输:参数和返回值通过Binder进行序列化和反序列化传输
  5. 应用技术管理:管理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通信代码。

image.png

Binder生命周期管理

Binder引用计数:

  1. 增加引用计数:Binder对象被传递给其他进程,引用计数会增加。通过transact传递Binder对象,引用计数加一。
  2. 减少引用计数:Binder对象不再使用时,应用计数减少。通过unlinkToDeath解除Binder的死亡通知,计数减一。

Binder死亡通知:

  1. 设置死亡通知:通过linkToDeath方法,当Binder对象所在的进程终止时,会收到死亡的通知。
  2. 处理死亡通知:重写Binder.DeathRecipient接口,实现binderDied方法处理Binder对象所在进程的死亡情况。