1:IPC 原理
从进程角度来看 IPC 机制
每个 Android 的进程,只能运行在自己进程所拥有的虚拟地址空间。对应一个4GB 的虚拟地址空间,其中 3GB 是用户空间,1GB 是内核空间,当然内核空间的大小是可以通过参数配置调整的。对于用户空间,不同进程之间彼此是不能共享的,而内核空间却是可共享的。Client 进程向 Server 进程通信,恰恰是利用进程间可共享的内核内存空间来完成底层通信工作的,Client 端与Server 端进程往往采用 ioctl 等方法跟内核空间的驱动进行交互。
如图所示:
2:Binder 原理
Binder 通信采用 C/S 架构,从组件视角来说,包含 Client、Server、ServiceManager 以及 binder 驱动,其中 ServiceManager 用于管理系统中的各种服务。架构图如下所示:
可以看出无论是注册服务和获取服务的过程都需要 ServiceManager,需要注意的是此处的 Service Manager 是指 Native 层的 ServiceManager(C++),并非指 framework 层的 ServiceManager(Java)。
/frameworks/base/core/java/android/os/ServiceManager.java
在这里主要是想查看:ServiceManager.cpp是哪个文件里面的?
public static native IBinder waitForService(@NonNull String name);
在这里注册的:frameworks/base/core/jni/android_os_ServiceManager.cpp
frameworks/native/cmds/servicemanager/ ServiceManager.cpp
ServiceManager 是整个Binder 通信机制的大管家,是 Android 进程间通信机制 Binder 的守护进程,要掌握Binder 机制,首先需要了解系统是如何首次启动 Service Manager。当Service Manager 启动之后,Client 端和 Server 端通信时都需要先获取Service Manager 接口,才能开始通信服务。
图中 Client/Server/ServiceManager 之间的相互通信都是基于Binder 机制。既然基于 Binder 机制通信,那么同样也是 C/S 架构,则图中的3 大步骤都有相应的Client 端与 Server 端。
1. 注 册 服 务 (addService) : Server 进 程 要先注册Service到ServiceManager。该过程:Server 是客户端,ServiceManager 是服务端。
2. 获 取 服 务 (getService) : Client 进 程 使 用 某个Service 前,须先向ServiceManager 中获取相应的 Service。该过程:Client 是客户端,ServiceManager 是服务端。
3. 使用服务:Client 根据得到的 Service 信息建立与Service 所在的Server 进程通信的通路,然后就可以直接与 Service 交互。该过程:client 是客户端,server 是服务端。
图中的 Client,Server,Service Manager 之间交互都是虚线表示,是由于它们彼此之间不是直接交互的,而是都通过与 Binder 驱动进行交互的,从而实现IPC通信方式。其中 Binder 驱动位于内核空间,Client,Server,Service Manager 位于用户空间。Binder 驱动和 Service Manager 可以看做是Android 平台的基础架构,,而 Client 和 Server 是 Android 的应用层,开发人员只需自定义实现client、Server 端,借助 Android 的基本平台架构便可以直接进行IPC 通信。
3 C/S 模式
BpBinder(客户端)和 BBinder(服务端)都是 Android 中Binder 通信相关的代表,它们都从 IBinder 类中派生而来,关系图如下:
client 端:BpBinder.transact()来发送事务请求;
server 端:BBinder.onTransact()会接收到相应事务。