Android 进阶——Framework核心 之Binder Native成员类详解

Posted CrazyMo_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 进阶——Framework核心 之Binder Native成员类详解相关的知识,希望对你有一定的参考价值。

文章大纲

引言

上一篇文章总结了Binder IPC的相关理论,不过呢,和这篇文章关系不大,不存在先后的顺序,因为这篇文章是主要解读Binder 代码层面主要家族成员类功能和部分代码的,目的是从代码和逻辑设计对Binder 有更深的理解。

一、Native 家族核心成员关系图

android 中Binder native 家族主要的头文件位于/frameworks/native/include/binder/,实现位于/frameworks/native/libs/binder/,这些代码最终会被编译成动态链接库libbinder.so(即Binder库),供其他进程调用。

find -type f -name “*.mk” | xargs grep “keyword”

主要有 IBinder、BBinder、BpBinder、BnInterface、BpInterface、IInterface类

二、Native 家族核心成员源码概述

Android中Java 、Native层使用同一套架构实现Binder服务,Java层通过JNI调用Native 层的实现,Binder 底层不需要关心上层的实现细节,只需要和BBinderBpBinder通信即可。BpBinder和BBinder是具有映射的关系,BpBinder为客户端BBinder为服务端,BpBinder通过前面所说的handle去标识其对应的客户端BBinder。

1、IInterface

\\frameworks\\native\\include\\binder\\IInterface.h 、\\frameworks\\native\\libs\\binder\\IInterface.cpp

IInterface是为客户端进程的上层应用提供接口服务的基类接口并继承了RefBase,通常其派生类实现了Binder服务的业务方法,通过这个接口客户端进程的上层应用能像使用本地对象一样直接使用远程的BBinder提供的Binder服务。简而言之,Binder代理对象主要负责与应用程序通信,与引用对象互相独立,代理对象可以有很多个实例但是指向的是同一个Binder引用对象。

1.1、DECLARE_META_INTERFACE 宏

执行DECLARE_META_INTERFACE 宏时添加:静态成员变量descriptor、静态函数asInterface()以及类的构造函数和析构函数,自己在native 开发Binder时也可以直接使用。

#define DECLARE_META_INTERFACE(INTERFACE) \\
    static const String16 descriptor; \\
    static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \\
    virtual String16 getInterfaceDescriptor() const; \\

I##INTERFACE##表示连接两个宏定义,而INTERFACE是模板名,被当作是宏定义,若INTERFACE被ServiceManager替代则I##INTERFACE就是IServiceManager

其中asInterface()函数主要是用于把Binder引用(BpBinder的派生类)转成代理对象(IInterface派生类),在客户进程中执行则会新建一个Binder代理对象(里面包含了引用对象);在服务端进程中则直接返回参数的指针,因为在服务端进程中可以直接通过指针调用服务类,无需通过代理对象去调用了。

1.2、IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 宏

初始化了一个变量descriptor,实现了I##INTERFACE2个函数:getInterfaceDescriptor ()和 asInterface()

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \\
    const String16 I##INTERFACE::descriptor(NAME); \\
    String16 I##INTERFACE::getInterfaceDescriptor() const  \\
        return I##INTERFACE::descriptor; \\
     \\
    sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \\
     \\
        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; \\
    

\\ 则表示一行的结束标志

1.3、sp< IInterface > BnInterface< INTERFACE >::queryLocalInterface(const String16& _descriptor) 模板函数

根据传入的字符串描述符查询对应的IInterface 对象。

1.4、static sp< IBinder > asBinder(const IInterface*) 安全触发onAsBinder函数

本质上就是调用传入的形参的onAsBinder函数。

2、IBinder

Base class and low-level protocol for a remotable object.

IBinder继承自RefBase是所有可远程通信对象的基类,定义了最底层的通信协议,Java 层的IBinder的能力本质上就是native 层IBinder提供的。

RefBase(BpRefBase继承自RefBase) 是Android 智能指针相关的引用计数基类,继承了RefBase 的派生类对象可以通过强、弱指针维护其生命周期。

3、BBinder(Binder本地对象)

frameworks\\native\\include\\binder\\Binder.h,\\frameworks\\native\\libs\\binder\\Binder.cpp

BBinder直接继承自IBinder,Binder 服务能力的提供者(服务端Binder对象),实现了抽象的IPC 通用通信接口——transact函数。一个提供Binder服务的类必须继承BBinder,BBinder 是服务端的中心,真正的函数实现是在BBinder的派生类中。

3.1、transact 和onTransact函数

BBinder 主要负责和底层的IPCThread 通信,当一个Binder代理对象通过Binder驱动向一个Binder本地对象发出一个IPC调用时,Binder驱动的IPCThread会调用BBinder的transact函数,进而触发onTransact 函数来分发与业务相关的IPC。当Binder调用从Binder驱动传递过来时,IPCThread 会调用BBinder的transact函数。

4、BpBinder

\\frameworks\\native\\include\\binder\\BpBinder.h、\\frameworks\\native\\libs\\binder\\BpBinder.cpp

BpBinder 是BBinder 对象在客户端进程的引用对象,客户端直接通过使用BpBinder来获得远程对象的能力。

4.1、BpBinder构造函数

BpBinder::BpBinder(int32_t handle)
    : mHandle(handle)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(NULL)

    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    IPCThreadState::self()->incWeakHandle(handle);

创建IPCThreadState对象并增加自身的弱引用计数。

4.2、mHandle 引用对象句柄

在BpBinder中有一个**int32_t类型的成员变量,存储的是Client组件对应Binder驱动中的Binder引用对象的句柄,**成员函数handle() 的返回值就是这个句柄。

每一个Client组件在Binder驱动都对应着一个Binder 引用对象,Client组件就是通过这个句柄值和Binder驱动中的Binder引用对象建立映射关系的。

4.3、transact( uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags = 0)

transact 函数主要用于向Server进程的Server组件发送IPC请求。当向Server 组件发起IPC 请求时,会把BpBinder类的mHandle和通信数据一起发给Binder驱动,Binder驱动根据mHandle句柄先找到Binder引用对象,进而找到对应的Binder实体对象,最后将通信数据通过映射内存方式发送给对应的Server组件。

5、BpRefBase

而BpRefBase中间接持有BpBinder对象:通过调用remote函数就可以获取。

6、BnInterface 和BpInterface

\\frameworks\\native\\include\\binder\\IInterface.h头文件下还定义了两个Binder库中重要的模板类。

Binder库成员代称角色关联的Binder驱动对象
BnInterfaceBinder本地对象作为Server组件Binder实体对象
BpInterfaceBinder代理对象作为Client组件Binder引用对象
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder

public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;
protected:
    virtual IBinder*            onAsBinder();
;

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase

public:
                                BpInterface(const sp<IBinder>& remote);
protected:
    virtual IBinder*            onAsBinder();
;

INTERFACE是一个自定义的Server组件接口占位符

BnInterface 继承了BBinder和INTERFACE,而BBinder 直接继承自IBinder。

6.1、BpInterface构造函数

BpInterface声明在IInterface.h中,是一个模板类,remote初始化了其父类BpRefBase并把remote保存父类BpRefBase的成员变量mRemote中。

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)


而构造函数为

BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)

    extendObjectLifetime(OBJECT_LIFETIME_WEAK);

    if (mRemote) 
        mRemote->incStrong(this);
        mRefs = mRemote->createWeak(this);
    

mRemote就等于之前的new Bpbinder。

7、ProcessState 初始化binder设备

篇幅问题,详情参见下文。

8、IPCThreadState 负责与Binder驱动交互

篇幅问题,详情参见下文。

9、Binder 对象引用计数管理

篇幅问题,详情参见下文。

10、IInterface vs IBinder?

留一个疑问给大家自己思考,未完待续…

以上是关于Android 进阶——Framework核心 之Binder Native成员类详解的主要内容,如果未能解决你的问题,请参考以下文章