一、Binder的概念
1. 从IPC角度来说,Binder是Android中的一种跨进程通信方式
2. Binder是基于C/S结构的一种面向对象的IPC机制。包含:Client、Server、Binder驱动和ServiceManager四大组成部分
二、与传统Linux的通信机制对比
1. 目前linux支持的IPC包括传统的管道,消息队列、共享内存、信号量,以及socket,但只有socket支持Client-Server的通信方式。
- socket是一套通用的网络通信方式,其传输效率不高且在socket的连接建立过程和中断连接过程都是有一定开销的。
- 消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程。
- 共享内存:在传输时没有拷贝数据,但其控制机制复杂(比如跨进程通信时,需获取对方进程的pid,得多种机制协同操作)
2. Android为每个安装好的应用程序分配了自己的 UID,故进程的UID是鉴别进程身份的重要标志。
3. 传统IPC没有任何安全措施,完全依赖上层协议来确保。IPC访问接入点是开放的,无法建立私有通道,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。
4. 基于以上原因,Android需要建立一套新的IPC机制来满足系统对通信方式,传输性能和安全性的要求,这就是Binder:
- 采用C/S的通信模式。
- 有更好的传输性能:传输过程只需一次拷贝
- 安全性更高:Binder机制的UID/PID是由Binder机制本身在内核空间添加身份标识,安全性高;可以建立私有通道
三、Binder的通信机制
1. 在android中,有很多Service都是通过binder来通信的,Binder在C/S中的流程如下:
- Server注册Service >> Server通过Binder驱动向ServiceManager注册,声明可以对外提供服务。ServiceManager中会保留一份映射表
- Client申请使用Service >> Client想要请求Server的数据时,需要先通过Binder驱动向ServiceManager请求Server的Binder引用
- Client拿到这个Binder引用后,就可以通过Binder驱动和Server进行通信了。Server响应请求后,需要再次通过Binder驱动将结果返回给Client。
2. SM一方面管理Server所提供的服务,同时又响应Client的请求并为之分配相应的服务。
这种通信方式的好处是: a.service和Client请求便于管理,b.在开发时,只需为Client建立到Server的连接,就可以实现Server相应功能
四、Binder的通信机制流程
1. Binder的通信模型。我们可以发现:
- Client和Server是存在于用户空间
- Client与Server通信的实现,是由Binder驱动在内核空间实现
- SM作为守护进程,处理客户端请求,管理所有服务项。
2. ServiceManager和Binder驱动属于两个不同的进程,它们是为Client和Server之间的进程间通信服务的,也就是说Client和Server之间的进程间通信依赖ServiceManager和Binder驱动之间的进程间通信。两个互相依赖的进程通信,到底是哪一个会先进行呢,Android的解决思路:
当Android系统启动后,会创建一个名称为servicemanager的进程,这个进程通过一个约定的命令 “BINDERSETCONTEXT_MGR” 向Binder驱动注册,申请成为ServiceManager。
Binder驱动会自动为该ServiceManager创建一个Binder实体。并且这个Binder实体的引用在所有的Client中都为0,也就说各个Client通过这个0号引用就可以和ServiceManager进行通信。Server通过0号引用向ServiceManager进行注册,Client通过0号引用就可以获取到要通信的Server的Binder引用。
3. Client拥有自己Binder的实体,以及Server的Binder的引用;Server拥有自己Binder的实体,以及Client的Binder的引用。
4. 匿名Binder:建立点对点的私有通道。在 Binder通信中,并不是所有通信的Binder实体都需要注册给SM,Server可以通过已建立的实体Binder连接将创建的 Binder实体传给Client。而这个Binder没有向SM注册名字。这样Server与Client的通信就有很高的隐私性和安全性。