Binder机制是Android系统中的一种IPC机制(进程间通信)。
为什么会有IPC机制?
1:进程隔离:
因为Android系统中进程之间存在进程隔离。Android系统会为每个进程分配一定的内存空间,对于不同的进程
他们的内存空间和数据是不共享的,这样做的目的是为了避免进程之间互相操作数据的情况发生,
保证进程的安全性。为了实现进程隔离,系统采用了虚拟地址的方式。
2:进程功能有限:
因为每个进程的功能是有限的,不可能将所有事情都实现。比如,某个app想要使用播放音乐的功能,他就需要
去调用音乐播放服务。但是由于每个进程的内存是隔离的,所以就需要进程间通信的技术。
Linux系统本身由很多IPC机制(Socket,管道,共享内存等),为什么Android系统还要实现Binder?
1:传输性能:
Linux内存空间=内核空间(驱动+操作系统)+用户空间。为了保证内核空间的安全,内核空间
和用户空间是隔离的。内核空间可以访问所有的内存空间,但是用户空间不可以访问内核空间。
用户空间访问内核空间的唯一合法方式就是系统调用(System call)
,即通过copy_to_user和copy_frome_user。copy_to_user将数据从内存空间拷贝到用户空间
copy_frome_user从用户空间拷贝到内存空间。
传统的IPC,发送方拷贝到内核空间->内核空间拷贝到接收方。两次(拷贝两次)Socket,管道
Binder,发送方拷贝到内核空间->内核空间和接收方内存映射。1次(拷贝加内存映射)Binder
共享内存不需要拷贝,但是维护起来较为复杂。综合来说Binder性能最佳。
2:安全性:Client端的标识uid/pid由Binder设置,提高了安全性。
Binder的通信模型是C/S架构,想要实现CS通信需要满足两个条件:
1:Server必须有确定的接入点或者说地址来接收请求,并且Client有方式可以拿到接入点或者地址;
2:有协议来传输数据;
如网络通信中,ip就是地址而TCP/ip协议就是用来传输数据的协议。
而在Binder机制中,对Server而言Binder就是对外的访问接入点,对Client而言Binder就是访问服务的管道,要访问必须先建立管道的链接并获取到管道;
Binder实体位于远端服务中,而它的引用遍布整个系统中。Client通过拿到服务Binder的引用,进而通过Binder的引用去引用远端服务的方法;
SMgr和实名Binder:
Server中Binder实体携带名称----->Binder驱动创建实体节点和SMgr对Binder实体的引用---->SMgr拿到引用和名称放入查找表。
SMgr生成的过程:
1:打开binde驱动(/dev/binder)文件;
2:SM和binder驱动建立内存映射;
3:SM通知binder驱动自己为守护进程,即端口号为0的那个服务;
4:SM进入循环等待,等待请求的到来(类似Handler中Looper的等待);
Client获取Binder引用的过程:
Client通过端口号0访问SMgr----请求查找某服务的引用----拿到引用通过Binder驱动访问该服务
匿名Binder:
Client通过实名BInder和Server建立链接,Server将服务内的匿名Binder引用发送给Client。通过这个匿名的Binder发送消息则建立了私密的通道。
