when——从Android系统启动简单说起
从最早的电源打开,系统启动开始,init进程解析init.ic配置文件,并启动Zygote进程,Zygote进程启动过程中所启动的SystemServer进程被创建后,启动了Binder线程池,开始作用于进程间的通信。
What——Binder:是什么?
- 从机制、模型角度来说:
- 定义:Binder是一种Android中实现跨进程通信(IPC)的方式。即Binder机制模型
- 作用:在Android中实现跨进程通信。
- 从模型的接口、组成来说:
- 定义:Binder是一种虚拟的物理设备驱动。即Binder驱动
- 作用:连接Service进程、Client进程和Service Manager进程
- 从Android代码的实现角度来说:
- 定义:Binder是一个类,实现了IBinder接口。即Binder类
- 作用:将Binder机制模型以代码的形式具体实现在Android中
where——通信模型
Binder是一套基于C/S架构的。由一系列的组件组成,主要包括:Client,Server,Service Manager和Binder驱动。其中Client,Service和Service Manager是在用户空间的,Binder驱动是在内核空间的。Client和Service是由用户是用户实现的,Binder驱动和Service Manager是系统实现的。Client,Server和Service Manager都可以通过系统调用open,mmap和ioctl来访问设备文件/dev/binder。从而实现与Binder驱动的交互间接实现进程间的通信。
Why——为什么要使用Binder?
性能方面:
在移动设备上(性能受限制的设备,比如要省电),广泛地使用跨进程通信对通信机制的性能有严格的要求,Binder相对出传统的Socket方式,更加高效。Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,共享内存方式一次内存拷贝都不需要,但实现方式又比较复杂。
安全方面:
传统的进程通信方式对于通信双方的身份并没有做出严格的验证,比如Socket通信ip地址是客户端手动填入,很容易进行伪造,而Binder机制从协议本身就支持对通信双方做身份校检,因而大大提升了安全性。
首先了解Binder通信的四个角色
首先了解Binder通信的四个角色:
- Client进程:使用服务的进程。
- Server进程:提供服务的进程。
- ServiceManager进程:ServiceManager的作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder名字获得对Server中Binder实体的引用。
- Binder驱动:(驱动负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。)
How——Binder运行机制
Binder运行机制:
看图:Binder原理(图片).jpg
图中Client/Server/ServiceManage之间的相互通信都是基于Binder机制。既然基于Binder机制通信,那么同样也是C/S架构,则图中的3大步骤都有相应的Client端与Server端。
- 注册服务(addService):Server进程要先注册Service到ServiceManager。该过程:Server是客户端,ServiceManager是服务端。
- 获取服务(getService):Client进程使用某个Service前,须先向ServiceManager中获取相应的Service。该过程:Client是客户端,ServiceManager是服务端。
- 使用服务: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通信。
【示例说明——】
总结:
- Binder框架定义了四个角色:Server,Client,ServiceManager以及Binder驱动。其中Server,Client,ServiceManager运行于用户空间,驱动运行于内核空间。
- 这四个角色的关系类似:Server是服务器,Client是客户终端,ServiceManager是服务注册中心(类似房屋中介)。要进行Client-Server之间的通信,从面向对象的角度,在Server内部有一个Binder实体,在Client内部有一个Binder对象的引用,其实就是Binder的一个代理,Client通过对Binder引用间接的操作Server内部的Binder实体,这样就实现了通信。
ServiceManager:怎么才能够实现正确的Client调用正确的Server呢
问题:会有很多个提供不同服务的Server(比如有媒体播放服务,音视频捕获服务等),而且会有很多Client(比如多个应用都要调用媒体播放服务),那么我们怎么才能够实现正确的Client调用正确的Server呢?
就好比房客怎么才能够租到自己想要租的房子(联系上房东),这个时候中介就起到重要作用,房东想要出租自己的房子就必须要到中介注册,房客想要租房子就要去中介那里找,同样的道理,这里Client就是房客,Server就是房东,ServiceManager就是房屋中介,每个Server如果要提供服务就必须要去ServiceManager那里去注册,ServiceManager在一张查找表中记录一个Server的名字,对应着Server的引用。Client想要获得Server,必须通过名字到ServiceManager取找Server的引用,获得这个Server的binder引用,通过这个binder引用去和Server通信。