一、Binder机制概述
在Android开发中,很多时候我们需要用到进程间通信,所谓进程间通信,实现进程间通信的机制有很多种,比如说socket、pipe等,Android中进程间通信的方式主要有三种:
1.标准Linux Kernel IPC 接口;
2.标准D-BUS接口;
3.Binder接口。
其中,Binder机制是使用最且最被认可的,因为Binder机制有以下优点:
1.相对于其它IPC机制,Binder机制更加简洁和快速;
2.消耗的内存相对更少;
3.传统的IPC机制可能会增加进程的开销,以及出现进程过载和安全漏洞,Binder机制则有效避免和解决了这些问题。
Binder机制是Android系统的核心机制,几乎贯穿于整个Android系统,Android系统基本上可以看作是一个基于binder通信机制的C/S架构,Binder就像网络,把Android系统的各个部分连接到了一起。利用Binder机制,可以实现以下功能:
1.用驱动程序来推进进程间通信;
2.通过共享内存来提高性能;
3.为进程请求分配每个进程的线程池;
4.针对系统中的对象引入了引用计数和跨进程的对象引用映射;
5.进程间同步调用。
二、Binder机制的工作流程
1.客户端获取服务端的带来对象(proxy)。我们需要明确的是客户端进程并不能直接操作服务端中的方法,如果要操作服务端中的方法,那么有一个可行的解决方法就是在客户端建立一个服务端进程的代理对象,这个代理对象具备和服务端进程一样的功能,要访问服务端进程中的某个方法,只需要访问代理对象中对应的方法即可;
2.客户端通过调用代理对象向服务端发送请求。
3.代理对象将用户请求通过Binder驱动发送到服务器进程;
4.服务端进程处理客户端发过来的请求,处理完之后通过Binder驱动返回处理结果给客户端的服务端代理对象;
5.代理对象将请求结果进一步返回给客户端进程。
通过以上5个步骤,就完成了一次Binder通信。
三、Binder机制的组成
Binder机制由三部分组成,即:
1.Client;
2.Server;
3.ServiceManager。
三部分组件之间的关系:
1.Client、Server、ServiceManager均在用户空间中实现,而Binder驱动程序则是在内核空间中实现的;
2.在Binder通信中,Server进程先注册一些Service到ServiceManager中,ServiceManager负责管理这些Service并向Client提供相关的接口;
3.Client进程要和某一个具体的Service通信,必须先从ServiceManager中获取该Service的相关信息,Client根据得到的Service信息与Service所在的Server进程建立通信,之后Clent就可以与Service进行交互了;
4.Binder驱动程序提供设备文件/dev/binder与用户空间进行交互,Client、Server和ServiceManager通过open和ioctl文件操作函数与Binder驱动程序进行通信;
5.Client、Server、ServiceManager三者之间的交互都是基于Binder通信的,所以通过任意两者这件的关系,都可以解释Binder的机制。
四、Binder驱动的实现简介。
1.Binder采用了AIDL来描述进程间的接口;
2.Binder是一个特殊的字符型设备,设备节点为dev/binder。
3.Binder驱动程序由以下两个文件实现:
①kernel/drivers/staging/binder.h
②kernel/drivers/staging/binder.c
4.在Binder驱动的实现过程中,以下函数起着关键作用:
①使用binder_ioctl()函数与用户空间交换数据;
②BINDER_WRITE_READ用来读写数据,数据包中的cmd域用于区分不同的请求;
③使用binder_thread_write()函数来发送请求或返回结果,在binder_thread_write()函数中,通过调用binder_transaction()函数来转发请求并返回结果.当收到请求时,binder_transaction()函数会通过对象的handle找到对象所在的进程,如果handle结果为空,则认为此对象是context_mgr,然后把请求发给context_mgr所在的进程,并将请求中所有的Binder对象放到RB树中,最后把请求放到目标进程的队列中以等待目标进程的读取。;
④使用binder_thread_read()函数来读取结果;
⑤在函数binder_parse()中实现数据解析工作。
五、Binder驱动程序中的数据结构
1.binder_work。binder_work表示在binder驱动中进程要处理的工作项。
2.binder_node。binder_node用于定义Binder实体对象。Android系统中每一个Srevice组件在Binder驱动程序中都对应一个Binder实体对象。驱动中的Binder实体也叫做“节点”,你属于提供实体的进程;
3.binder_ref。binder_ref用于描述一个Binder引用对象。Android系统中每一个Client组件在Binder驱动程序中都对应一个Binder引用对象;