用户空间的Binder设计

上面是用户空间中Binder模型图,该图仅仅只描述出Server的相关类图,并没有Client部分。不过不要紧,通过这个Server的模型图,就能理清用户空间的Binder框架。

前面说过,Server是以服务的形式注册到ServiceManager中,而Server在Client中则是以远程服务的形式存在的。因此,这个图的主干就是理清楚本地服务和远程服务这两者之间的关系。
"本地服务"就是Server提供的服务本身,而"远程服务"就是服务的代理;"服务接口"则是抽象出了它们的通用接口。这3个角色都是通用的,对于不同 的服务而言,它们的名称都不相同。例如,对于MediaPlayerService服务而言,本地服务就是MediaPlayerService自身,远 程服务是BpMediaPlayerService,而服务接口是IMediaPlayerService。当Client需要向 MediaPlayerService发送请求时,它需要先获取到服务的代理(即,远程服务对象),也就是BpMediaPlayerService实 例,然后通过该实例和MediaPlayerService进行通信。

图中的ProcessState和IPCThreadState都是采用单例模式实现的,它们的实例都是全局的,而且只有唯一一个。

(01) 当Server启动之后,它会先将自己注册到ServiceManager中。注册时,Binder驱动会创建Server对应的Binder实体,并 将"Server对应的本地服务对象的地址"保存到Binder实体中。注册成功之后,Server就进入消息循环,等待Client的请求。
(02) 当Client需要和Server通信时,会先获取到Server接入点,即获取到远程服务对象;而且Client要获取的远程服务对象是"服务接口"类 型的。Client向ServiceManager发送获取服务的请求时,会通过IPCThreadState和Binder驱动进行通信;当 ServiceManager反馈之后,IPCThreadState会将ServiceManager反馈的"Server的Binder引用信息"保 存BpBinder中(具体来说,BpBinder的mHandle成员保存的就是Server的Binder引用信息)。然后,会根据该 BpBinder对象创建对应的远程服务。这样,Client就获取到了远程服务对象,而且远程服务对象的成员中保存了Server的Binder引用信 息。
(03) 当Client获取到远程服务对象之后,它就可以轻松的和Server进行通信了。当它需要向Server发送请求时,它会调用远程服务接口;远程服务能 够获取到BpBinder对象,而BpBinder则通过IPCThreadState和Binder驱动进行通信。由于BpBinder中保存了 Server在Binder驱动中的Binder引用;因此,IPCThreadState和Binder驱动通信时,是知道该请求是需要传给哪个 Server的。Binder驱动通过Binder引用找到对应的Binder实体,然后将Binder实体中保存的"Server对应的本地服务对象的 地址"返回给用户空间。当IPC收到Binder驱动反馈的内容之后,它从内容中找到"Server对应的本地服务对象",然后调用该对象的 onTransact()。不同的本地服务都可以实现自己的onTransact();这样,不同的服务就可以按照自己的需求来处理请求。

原文地址:https://www.cnblogs.com/mgstone/p/5818274.html