Android跨进程通信Binder机制浅析

2019-04-16  本文已影响0人  门心叼龙

本文为自己多年来在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 即进程间通信

2. 什么是Binder?

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

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

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

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

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

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

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

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用于管理系统中的各种服务

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()会接收到相应事务。

上一篇 下一篇

猜你喜欢

热点阅读