Android跨进程通信Binder机制浅析

本文为自己多年来在Android实战开发过程中总结归纳的一些常见问题,现在分享出来希望对初学者有所帮助。

本文出自门心叼龙的博客,转载请注明出处: https://blog.csdn.net/geduo_83/article/details/86560675

目录

1. 什么IPC?Linux中现有的IPC通信方式都有哪些?

2. 什么是Binder?

3. 为什么 Android 要采用 Binder 作为 IPC 机制?

4. Binder通信中的内存分配?

5. framework Binder架构图?


1. 什么IPC?Linux中现有的IPC通信方式都有哪些?

IPC的全称是:Inter-Process Communication 即进程间通信

  • 1.1 管道:在创建时分配一个page大小的内存,缓存区大小比较有限
  • 1.2 消息队列:信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信;
  • 1.3 共享内存:无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决;
  • 1.4 套接字:作为更通用的接口,传输效率低,主要用于不通机器或跨网络的通信;
  • 1.5 信号量:常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段
  • 2.6 信号:不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等;

2. 什么是Binder?

Binder是基于Open-Binder开发的,是Android系统专有的跨进程通信实现机制,它位于Linux内核层,具有性能好,稳定性强、安全性强的特点,在整个Android操作系统中具有很高的江湖地位,可以说无Binder,不Android

3. 为什么 Android 要采用 Binder 作为 IPC 机制?

是否Android系统内部所有的进程都采取的Binder通信?
不是, Zygote采用的是Socket、杀死进程采用的是信号

  • 3.1 从性能的角度

数据拷贝次数:Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,但共享内存方式一次内存拷贝都不需要;从性能角度看,Binder性能仅次于共享内存。

  • 3.2 从稳定性的角度

Binder是基于C/S架构的,简单解释下C/S架构,架构清晰明朗,Server端与Client端相对独立,稳定性较好;而共享内存实现方式复杂,没有客户与服务端之别, 需要充分考虑到访问临界资源的并发同步问题,否则可能会出现死锁等问题;从这稳定性角度看,Binder架构优越于共享内存。

  • 3.3 从安全的角度

传统IPC只能由用户在数据包里填入UID/PID;另外,可靠的身份标记只有由IPC机制本身在内核中添加。其次传统IPC访问接入点是开放的,无法建立私有通道。从安全角度,Binder的安全性更高。

  • 3.4 从语言层面的角度

大家多知道Linux是基于C语言(面向过程的语言),而Android是基于Java语言(面向对象的语句),从语言层面,Binder更适合基于面向对象语言的Android系统,对于Linux系统可能会有点“水土不服”。

  • 3.5 从公司战略的角度

4. Binder通信中的内存分配?

当Client端与Server端发送数据时,Client(作为数据发送端)先从自己的进程空间把IPC通信数据copy_from_user拷贝到内核空间,而Server端(作为数据接收端)与内核共享数据,不再需要拷贝数据,整个过程只发生一次内存拷贝。一般地做法,需要Client端进程空间拷贝到内核空间,再由内核空间拷贝到Server进程空间,会发生两次拷贝。对于共享内存虽然效率高,但是对于多进程的同步问题比较复杂,而管道/消息队列等IPC需要复制2两次,效率较低

image
image.gif

5. framework Binder架构图?

binder在framework层,采用JNI技术来调用native(C/C++)层的binder架构,从而为上层应用程序提供服务。 看过binder系列之前的文章,我们知道native层中,binder是C/S架构,分为Bn端(Server)和Bp端(Client)。对于java层在命名与架构上非常相近,同样实现了一套IPC通信架构。
Binder在整个Android系统中有这举足轻重的地位,在Native层有一套完整的binder通信的C/S架构(图中的蓝色),Bpinder作为客户端,BBinder作为服务端。基于naive层的Binder框架,Java也有一套镜像功能的binder C/S架构,通过JNI技术,与native层的binder对应,Java层的binder功能最终都是交给native的binder来完成。从kernel到native,jni,framework层的架构所涉及的所有有关类和方法见Binder类图。

image
image.gif

Binder通信采用C/S架构,从组件视角来说,包含Client、Server、ServiceManager以及binder驱动,其中ServiceManager用于管理系统中的各种服务

  • 注册服务(addService):

Server进程要先注册Service到ServiceManager。该过程:Server是客户端,ServiceManager是服务端。
获取服务(getService):Client进程使用某个Service前,须先向ServiceManager中获取相应的Service。该过程:Client是客户端,ServiceManager是服务端。

  • 使用服务:

Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互。该过程:client是客户端,server是服务端。
client端:BpBinder.transact()来发送事务请求;
server端:BBinder.onTransact()会接收到相应事务。

你可能感兴趣的:(Android跨进程通信Binder机制浅析)