binder初始篇

来源:互联网 发布:机械行业推广优化方案 编辑:程序博客网 时间:2024/06/05 08:45

1 Binder是什么?

binder是安卓系统远程调用机制,任何进程通过调用服务代理类的方法就像在本地进程调用服务实现类的方法一样。说到底binder是一种跨进程通信机制,当然它要依赖底层驱动才会有跨进程访问能力。


2 Binder设计框架

binder系统定义了四个角色,分别是serviceManager、server、client、binder驱动,前三个运行于用户空间,binder驱动于内核空间。驱动提供了跨进程通信底层支持,以致应用层无论用c/c++/java实现都能互相支持。

2.1 server

提供服务的进程,相当于注册服务实现类

2.2 client

使用服务的进程,相当于获取服务代理类

2.3 serviceManager

serviceManager是服务的管理者对于server来说,它要向client提供服务必须先向serviceManager注册服务,对于client来说,它想远程调用server提供的服务必须先向serviceManager获取服务。对于所有的server和client来说serviceManager就是server,serviceManager为它们提供注册、获取等功能的服务,所以所有的server和client进程首先以特定的手法获取serviceManager服务代理类


3 Binder分层分离

Android系统中的binder通信提供了Java和C++两个层次的支持,其中实现核心在C++层次中,Java层次只是对C++层次的再一层封装。两个层次对服务的代理类和实现类定义不同。在java中用aidi脚本就能自动生成服务代理类和服务实现类,我们只需要编写服务实现类具体的方法就可以,而在C++层次需要编写的类比较多。但它们低层的继承类定义是一样的,如与驱动通信的bqBiner类和BBinder类。


按照分层分离的思想,BBinder和BpBinder类被设计成只管传输数据,不会关心数据的具体含义。

3.1 BBinder类

server注册服务实质是先实例化一个服务实现类对象,然后把BBinder的地址和服务名称作为参数向serviceManager注册,因为BBinder类是服务实现类的父类服务实现类与BBinder类一一对应,也就是通过BBinder的地址在进程中能区分不同的binder服务binder服务实体在应用层表述为BBinder类。


BBbiner最重要的成员函数是transact,它的参数data和reply分别是在驱动接收到远端对应BpBinder的数据,和将要回复的数据。


如果code值不是PING_TRANSACTION的话,它将会调用onTransact函数。onTransact是一个虚拟函数,通常服务实现类会重载这个函数,根据code值的不同而调用不同的类成员函数,如需要回复数据给服务代理类,将会把数据填充到reply。

3.2 BpBinder类

client获取服务实质也是实例化一个服务代理类对象的过程。它根据服务的名字向serviceManager获取服务,binder驱动会返回对该服务的引用号(hander)给client,然后用hander值构造BpBinder。服务代理类的父类聚合了一个BpBinder类,所以要用BpBinder类去构造服务代理类。同样服务代理类与BpBinder类一一对应,也是通过不同的handle值构造的BpBinder在进程中能区分获取的不同binder服务binder服务引用在应用层表述为BpBinder类。


Bpbiner最重要的成员函数是transact,上层把数据打包成parcel类。它的参数data和reply分别是发向驱动的数据,和接收回复的缓冲区。


它将会调用IPCThreadState::self()->transact继续封装数据,参数还携带了进程中唯一的类成员参数mhandle,mhandle参数正是在BpBinder(int32_t handle)中初始化。IPCThreadState::self()->transact等等我们再来分析。


4 Binder相关接口和类

既然binder的核心实现在C++层,我们就先分析C++层的,先上一个类继承图


刚才说在C++层次上要编写类比较多,其实也就是三个,图中有颜色的类就是需要我们自己编写的。但安卓源码提供宏和类模板减少我们的代码量。比如我们要在C++层级使用binder,我们要怎样做呢?举个例子,实现一个GoodbyeService服务。


4.1 Ixxx

首先定义一个IGoodbyeService服务的接口



4.1.1 DECLARE_META_INTERFACE(GoodbyeService);
IMPLEMENT_META_INTERFACE(GoodbyeService, "android.media.IGoodbyeService");

宏定义展开后



4.2 Bpxxx

实现我们自己的服务代理类BpGoodbyeService


它通过继承类模板BpInterface<IGoodbyeService>从而继承了IGoodbyeService,并重载了saygoodbye_to函数。由上面的类继承图可以看出Bpxxx是继承BpRefBase的,remote()返回的是mRemote,我们会在后面分析的代码看到构造BpGoodbyeService时父类BpRefBase的类成员mRemote会记录到对应的BpBiner,Bpxxx聚合了Bpbinder从而remote()->transact最终还是会调用上面提及到的IPCThreadState::self()->transact。


4.2.1 BpInterface<ixxx>

类模板BpInterface<IGoodbyeService>



4.3 Bnxxx

实现我们自己的BnGoodbyeService实现



它通过继承类模板BnInterface<IGoodbyeService>从而继承了IGoodbyeService,并重载了saygoodbye_to函数。由上面的类继承图可以看出Bnxxx继承了BBinder,上面讲到BBbiner最重要的成员函数transact收到的code值不等于PING_TRANSACTION就会调用到BnGoodbyeService重载的onTransact函数。比如这次传输的code值为IGoodbyeService服务的接口中定义的GOODBYE_SVR_CMD_SAYGOODBYE_TO,就会调用到BnGoodbyeService本地方法saygoodbye_to。


4.3.1 BnInterface<ixxx>

类模板BnInterface<IGoodbyeService>



5 binder系列文章讲述思路

本binder系列文章按照情景分析的思路,源码完全注释的方式为大家介绍。read the fucking source code 

主要讲述

1、binder数据结构分析

2、serviceManager

3、server向serviceManager注册服务

4、client向serviceManager获取server提供服务

5、client使用server服务


6 参考文献

图文并茂,膜拜作者

https://my.oschina.net/youranhongcha/blog/149575

0 0