Binder机制

1、Binder简介

是Android平台上的一种跨进程通信(IPC)机制,从OpenBinder演化而来,采用CS通信方式,是客户端和服务端进行通信的媒介。

2、跨进程通信IPC原理

 

 

 

Android为每个进程提供了一个虚拟内存空间,并且每个Android进程只能运行在自己的进程所拥有的虚拟地址空间内,每个虚拟地址空间又分为用户空间与内核空间,其中,用户空间的数据不能在进程之间共享,而内核空间中的数据可以进行进程间的共享。因此Client与Server进程之间的通信要利用内核空间来完成底层通信工作。

3、Android C/S通信机制

 

 

在Android中不单单只有Client与Server,还有Service Manager,它用来管理各种服务。

当Server想要提供Service时,首先需要在Service Manager中注册该服务,当Client想访问Server提供的服务时,首先需要通过Service Manager来获取该服务,获取到之后才可以与Server进行通信来使用Server所提供的服务。

4、Binder通信机制

 

 

 

在该模型中,三个进程不能直接通过进程见API的调用,而必须要通过内核空间中的Binder驱动来完成进程之间的交换,每个进程都需要先把用户空间的数据交换到内核空间,然后在内核空间中,Binder驱动向用户控件提供一个设备文件/dev/binder,使得应用程序进程可以简洁的通过它来建立通信信道,进而完成进程间的数据交换和数据共享。

关键概念:

 

 

 

 Binder实体对象:Binder服务的提供者,类型是BBinder,也成为BBinder对象,一般存在于服务端进程中

 Binder引用对象:Binder实体对象在客户端进程的代表,类型为BpBinder,也称为BpBinder对象

 IBinder对象:Binder引用对象和Binder实体对象的统称,因为这两个类都继承自IBinder类

 Binder代理对象:代理对象也称为接口对象,主要是为客户端上层应用提供接口服务。类型为IInterface;Android将Binder引用对象和代理对象区分开的好处是一个Binder引用对象可以有多个Binder代理对象,方便应用层使用Binder引用对象

通信过程:

 注册服务

 

 

 

首先,Server在自己的进程向Binder驱动申请创建Binder实体,Binder驱动为这个Service创建位于内核的Binder实体节点和Binder引用,然后Server通过Binder驱动将Service名字和Service的Binder引用打包发送给Service Manager,Service Manager接收到数据包后,取出Service的名字和Binder引用,写入一张查找表。

这个过程中,Server作为Client端,Service Manager作为Server端。

 获取服务

 

 

 

注册服务之后,客户端想要去访问该服务首先需要先从Service Manager中获取该服务。

首先,Client利用hanle值为0的引用找到Service Manager【因为Android会自动为Service Manager分配一个hanle为0的Binder引用,这样Client端和Server端都可以通过hanle为0找到Service Manager,这样Service Manager就确定唯一】,然后Client向Service Manager发送访问XXXService的请求,通过Binder驱动发送给Service Manager,然后Service Manager从请求包中获取到XXXService的名字,然后在查找表中找到对应的条目,取出对应的Binder引用,然后在把Service名字和Binder引用打包通过Binder驱动回复给Client。这样Client就获取到它所要访问的Service的Binder引用。

 使用服务

 

 

 

取到Binder引用后,客户端就可以与服务端进行通信了。使用服务是发生于Client进程于Server进程之间的,因此无论是Client还是Server,都既是数据的发送方又是数据的接收方。Client持有Service的Binder引用和Client自身的Binder实体;Server持有Client的Binder引用和Service自身的Binder实体。

首先,发送方通过自身的Binder实体进行发送,把数据通过Binder引用发送给接收方,而Binder驱动会处理这个发送请求,利用内核空间的进程共享机制,处理过程如下:

 把发送方的数据放入写缓存(binder_write_read.write_buffer)(对于接收方来说是读缓存)

 接收方之前Service启动后一直处于阻塞状态并不断读取写缓存,当写缓存有数据时,就会读取数据并解析数据,发现是客户端的一个请求命令就会执行相应操作

 执行完之后同样会把返回结果放入写缓存中,此时的写缓存区对于Client来讲就是读缓存区,这样,Client就会读取到服务端所返回的数据

 

posted @ 2021-10-20 09:37  Sunshine_y  阅读(505)  评论(0编辑  收藏  举报