Binder 机制详解—Binder 本地框架

2014/05/26

本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接

上一篇博客介绍了Binder系统架构,其中说到Binder框架,本地层和Java层各自有一套实现。本篇博客将介绍Binder本地框架。

Binder本地框架

本地Binder框架包含以下类(frameworks/native/libs/binder):

RefBase, IInterface,BnInterface,BpInterface,BpRefBase,Parcel 等等

下图描述了实例《Binder service入门–创建native binder service》使用的ITestService与本地Binder框架类库的关系:(若看不清,请点击看大图)

native_binde_framework

  • 1)RefBase类(frameworks/native/include/utils/RefBase.h)

    引用的基类,android本地代码里采用了智能指针,有强指针,也有弱指针。不过不用纠结于这些细节。

  • 2)IInterface(frameworks/native/include/binder/IInterface.h)

    自定义的binder service接口必须继承自IInterface(如ITestService),它的onAsBinder方法为抽象方法,该方法的实现在BpInterface和BnInterface模版类里。

  • 3)BpRefBase(frameworks/native/include/binder/Binder.h)

    客户端间接用到该类,用于保存IBinder指针,remote()方法即返回IBinder指针。

  • 4)ITestService

    声明的binder service接口,在该接口里会声明所有提供的服务方法(使用纯虚函数),并用宏DECLARE_META_INTERFACE进行声明,这样会添加静态字段descriptor,静态方法asInterface,虚方法getInterfaceDescriptor,以及构造函数和析构函数。另外只需要使用IMPLEMENT_META_INTERFACE(INTERFACE, NAME)来即可定义用宏DECLARE_META_INTERFACE声明的这些方法和字段。

    DECLARE_META_INTERFACE宏的源码如下所示:

    ```cpp #define DECLARE_META_INTERFACE(INTERFACE) \ static const android::String16 descriptor; \ static android::sp<I##INTERFACE> asInterface( \ const android::sp& obj); \ virtual const android::String16& getInterfaceDescriptor() const;\ I##INTERFACE(); \ virtual ~I##INTERFACE(); ```

    若使用DECLARE_META_INTERFACE(TestService); 则会扩展为:

    ```cpp static const android::String16 descriptor; \ static android::sp asInterface( \ const android::sp& obj); \ virtual const android::String16& getInterfaceDescriptor() const; \ ITestService(); \ virtual ~ITestService(); ```

    宏函数IMPLEMENT_META_INTERFACE(INTERFACE, NAME)的源码如下所示:

    ```cpp #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ const android::String16 I##INTERFACE::descriptor(NAME); \ const android::String16& \ I##INTERFACE::getInterfaceDescriptor() const { \ return I##INTERFACE::descriptor; \ } \ android::sp<I##INTERFACE> I##INTERFACE::asInterface( \ const android::sp& obj) \ { \ android::sp<I##INTERFACE> intr; \ if (obj != NULL) { \ intr = static_cast<I##INTERFACE*>( \ obj->queryLocalInterface( \ I##INTERFACE::descriptor).get()); \ if (intr == NULL) { \ intr = new Bp##INTERFACE(obj); \ } \ } \ return intr; \ } \ I##INTERFACE::I##INTERFACE() { } \ I##INTERFACE::~I##INTERFACE() { } \ ```

    若使用IMPLEMENT_META_INTERFACE(TestService, "android.TestServer.ITestService")则会被替换成:

    ```cpp const android::String16 ITestService::descriptor("android.TestServer.ITestService"); \ const android::String16& \ ITestService::getInterfaceDescriptor() const { \ return ITestService::descriptor; \ } \ android::sp ITestService::asInterface( \ const android::sp& obj) \ { \ android::sp intr; \ if (obj != NULL) { \ intr = static_cast<ITestService*>( \ obj->queryLocalInterface( \ ITestService::descriptor).get()); \ if (intr == NULL) { \ intr = new BpTestService(obj); \ } \ } \ return intr; \ } \ ITestService::ITestService() { } \ ITestService::~ITestService() { } \ ``` </li>
  • 5)BpInterface(frameworks/native/include/binder/Binder.h)

    该类是一个模版类,需和某个继承自IIterface的类结合使用。

    它的声明如下所示:

    ```cpp template class BpInterface : public INTERFACE, public BpRefBase { public: BpInterface(const sp& remote); protected: virtual IBinder* onAsBinder(); }; ```

    因此BpInterface会继承两个类,一个父类是继承自IInterface的类,一个是BpRefbase,我们通常声明的客户端代理类会继承自BpInterface

    </li>
  • 6)BnInterface(frameworks/native/include/binder/IInterface.h)

    该类也是一个模版类,需和某个继承自IIterface的类结合使用。

    它的声明如下所示:

    ```cpp template class BnInterface : public INTERFACE, public BBinder { public: virtual sp queryLocalInterface(const String16& _descriptor); virtual const String16& getInterfaceDescriptor() const; protected: virtual IBinder* onAsBinder(); }; ```

    因此BnInterface也会继承两个类,一个父类是继承自IInterface的binder service接口类,一个是代表Binder service服务端的BBinder类,我们通常声明的服务端类会直接继承自BnInterface。

    该类实现了IBinder声明的另外两个方法,queryLocalInterface和getInterfaceDescriptor。

    </li> </ul>

    再介绍一个重要的宏函数interface_cast,它的源码如下所示:

    ```cpp template inline sp interface_cast(const sp& obj) { return INTERFACE::asInterface(obj); } ```

    若使用interface_cast < ITestService > (binder),会被扩展为:

    ```cpp inline sp< ITestService > interface_cast(const sp& obj) { return ITestService::asInterface(obj); } ```

    而ITestService::asInterface方法是ITestService接口声明时使用DECLARE_META_INTERFACE(TestService)声明的函数

    IServiceManager类图

    从先前的博客《Binder IPC程序结构》可知,servicemanager其实是init.rc里声明的本地服务,由init进程启动它作为一个单独的进程运行。不管是提供binder service的服务端还是使用binder service的客户端,都是在单独的进程,他们都需要首先获得servicemananger的IBinder指针,然后利用IBinder指针建立IServiceManager接口对象。通过《Binder 机制详解—重要函数调用流程分析》我们已经知道如何获得servicemananger的IBinder指针,并利用该IBinder指针建立IServiceMananger接口对象。

    IServiceManager相关类如下图所示:(若看不清,请点击看大图)

    native_binder_framework_servicemananger

    IServiceManager是表示servicemanager的接口,有如下方法:

    1) getService获得binder service引用,

    2) checkService获得binder service引用,

    3) addService添加binder service,

    4) listServices 列举所有binder service。

    servicemanager的binder service服务端其实是在frameworks/base/cmds/servicemanager 里实现,BnServiceMananger实际上并未使用。BpServiceMananger就是利用获得的IBinder指针建立的IServiceMananger对象的实际类型。

¥打赏5毛

取消

感谢您的支持,我会继续努力的!

扫码支持
赏个5毛,支持我把

打开支付宝扫一扫,即可进行扫码打赏哦

本篇目录