Android多进程通信之 Binder

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android多进程通信之 Binder相关的知识,希望对你有一定的参考价值。

参考技术A

在 Linux 中一个进程空间可以分为 用户空间 内核空间 ,不同的进程它们的用户空间数据不可共享,但是它们的内核空间的数据可共享,即所有进程共用 1 个内核空间。进程内用户空间和内核空间进行交互需通过系统调用。

android 系统时基于 Linux 内核的,Linux 已经提供了多种 IPC 方式,如下:

所以,Android 为啥又单独弄出一个 Binder 呢?主要有如下原因:

直观地说,Binder 是 Android 中的一个类,它实现了 IBinder 接口;从 Android Framework 角度来说,Binder 是 ServiceManager 连接各种 Manager(ActivityManager、WindowManager...) 和相应 ManagerService 的桥梁;从 Android 应用层来说,Binder 是客户端和服务端进行通信的媒介,当 bindService 的时候,服务端会返回一个包含了服务端业务调用的 Binder 对象,通过这个 Binder 对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于 AIDL 服务。

Binder 定义了四个角色:Server,Client,ServiceManager 和 Bidner 驱动,其中 Server、Client、ServiceManager 运行于用户空间,Binder 驱动运行于内核空间。

Binder 工作原理:

Android之Binder通信篇

参考技术A

Binder跨进程通信的本质是依赖内核驱动将属于不同Binder进程的数据,从原始进程复制到目标进程,这样就完成了跨进程通信了。

Binder通过独特的内存映射机制,在跨进程通信时,可以做到一次拷贝,两个空间同时使用!如下图:

Binder跨进程通信是要传递数据的,既然有数据必然要占用内存空间,Android系统规定每一个进程都有一块Binder内存区,也就是图1中的 共享内存 ,系统最多只能给该区域分配4M的物理内存,由于申请这块内存是通过系统的mmap函数完成的,所以整个映射机制又被称为mmap机制
为了把这部分说明白,就再盗图一张,命名图2吧!

对于Binder驱动,通过 binder_procs 链表记录所有创建的 binder_proc 结构体,binder 驱动层的每一个 binder_proc 结构体都与用户空间的一个用于 binder 通信的进程一一对应,且每个进程有且只有一个 ProcessState 对象,这是通过单例模式来保证的。在每个进程中可以有很多个线程,每个线程对应一个 IPCThreadState 对象,IPCThreadState 对象也是单例模式,即一个线程对应一个 IPCThreadState 对象,在 Binder 驱动层也有与之相对应的结构,那就是 Binder_thread 结构体。在 binder_proc 结构体中通过成员变量 rb_root threads,来记录当前进程内所有的 binder_thread。

Binder 线程池:每个 Server 进程在启动时创建一个 binder 线程池,并向其中注册一个 Binder 线程;之后 Server 进程也可以向 binder 线程池注册新的线程,或者 Binder 驱动在探测到没有空闲 binder 线程时主动向 Server 进程注册新的的 binder 线程。对于一个 Server 进程有一个最大 Binder 线程数限制,默认为16个 binder 线程,例如 Android 的 system_server 进程就存在16个线程。对于所有 Client 端进程的 binder 请求都是交由 Server 端进程的 binder 线程来处理的。

以上是关于Android多进程通信之 Binder的主要内容,如果未能解决你的问题,请参考以下文章

初识Android进程间通信之----Binder机制

Android 进阶8:进程通信之 Binder 机制浅析

Android 面试必备:Android多进程间通信—Binder机制

图文结合:通俗易懂的Android多进程间通信--binder机制

Android-zygote进程通信为啥不使用Binder?

❤️Android Binder原理图解❤️