Binder机制:拷贝一次,通过open, mmap, ioctl在dev/binder上实现的。
Client, Service, Service Manager三者之间的通信都是基于上面机制。
Service死亡接收通知:Service组件所在的进程可能会意外崩溃,Client在它所引用的Service组件死亡时获得通知。
Binder中的红黑树:在Binder驱动程序中,宿主进程通过一个binder_proc结构体来描述。宿主进程使用一个红黑树来维护它内部所有的Binder实体对象。
内核缓冲区:结构体binder_buffer用来描述一个内核缓冲区,是用来在进程间传输数据的。每个使用Binder进程间通信机制的进程在Binder驱动程序中都有一个内核缓冲区列表,用来保存Binder驱动为它所分配的内核缓冲区。
Binder 设备底层工作机制
Binder 驱动程序在目标设备上创建了一个Binder设备文件/dev/binder,这个设备文件的操作方法有:binder_open, binder_mmap, binder_ioctl
Binder 进程间通信库
Android 系统在应用程序框架层中将各种Binder驱动程序操作封装成一个Binder库。Service组件和Client组件分别使用BnInterface和BpInterface来描述(n代表native, p代表proxy),分别对应于Binder驱动程序中的Binder实体对象和Binder引用对象。
// 书中P188有一个应用实例帮助理解通信机制
Binder 对象引用计数技术:
Client 进程和Server进程的一次通信过程涉及四种类型对象:
Binder驱动中的Binder实体对象binder_node和Binder引用对象binder_ref,以及位于Binder库中的Binder本地对象BBinder和Binder代理对象BpBinder。
交互过程:
Service Manager的启动过程
SM 是Binder进程间通信机制上下文管理者,同时负责管理系统中的Service组件,并且向Client组件提供获取Service代理对象的服务。
SM 运行在独立的进程中,因此,Service组件和Client组件也需要通过进程间通信机制来和它交互。
SM 是由init进程负责启动的,init进程是在系统启动时启动的,因此,SM 也是在启动时启动的。启动步骤:一,调用函数binder_open打开设备文件/dev/binder,以及将它映射到本进程的地址空间;二,调用函数binder_become_context_manager将自己注册为Binder进程间通信机制的上下文管理者;三,调用函数binder_loop来循环等待和处理Client进程的通信请求。
Service Manager代理对象的获取过程
Service 组件在启动时,需要将自己注册到SM中,而Client组件在使用Service组件提供的服务之前,也需要通过SM来获得Service组件的代理对象。SM本身也是一个Service组件,但它的获取过程与其它的Service代理对象的获取有所不同。
对于一般的Service组件来说,Client进程首先要通过Binder驱动程序来获得它的一个句柄值,然后才可以根据这个句柄创建一个Binder代理对象,最后将这个Binder代理对象封装成一个实现了特定接口的代理对象。由于SM的句柄值恒为0,因此,获取它的一个代理对象的过程就省去了与Binder驱动程序交互的过程。
有了SM代理对象之后,Service组件就可以在启动时使用它的成员函数addService将自己注册到SM中,而Client组件就可以使用它的成员函数getService来获得一个指定名称的Service组件的代理对象。
Android系统在应用程序框架层的Binder库中提供了一个函数defaultServiceManager来获得一个SM代理对象。
Binder进程间通信机制的Java接口
Android 系统在应用程序框架层中提供了Binder进程间通信机制的Java接口,它们通过JNI方法来调用Binder库的C/C++接口,从而提供了执行Binder进程间通信的能力。
asInterface将句柄值为0的Java服务代理对象封装成一个SM的Java代理对象。 getIServiceManager将获得的ServiceManager的Java 代理对象保存在静态成员变量中,最后将它的IServiceManager接口返回给调用者。
Java服务接口的定义和解析
定义服务接口:在实现Java服务之前,首先定义服务接口。Android使用AIDL来定义服务接口。
在编译文件“服务接口.aidl”时,编译系统会生成一个中间文件“服务接口.java”。它包含一个Java接口,一个Java抽象类,和一个Java类。(例如,IFregService, IFregService.Stub, IFregService.Stub.Proxy)。Stub和Proxy都实现了IFregService接口,其中Stub类用来描述一个Java服务,而Proxy类用来描述一个Java服务代理对象。
步骤: