美文网首页
Android 基础学习(4) ---- Binder 简要原理

Android 基础学习(4) ---- Binder 简要原理

作者: 特立独行的佩奇 | 来源:发表于2022-11-20 17:13 被阅读0次
Binder 简介

Binder是用在Android系统中的一个进程间通信(IPC)机制,使用C/S 服务端和客户端通过Binder进行跨进程的数据交换;Binder继承自IBinder接口,因此IBinder接口最重要的一个方法是transact,所以虽然Android为了减少开发者开发工作量,采用了代理模式封装了一个复杂的Binder架构,但是其本质都是从源进程传递数据给目标进程;然后目标进程处理完后再把数据回传给源进程

Binder 的数据传输流程如下:

  • client 端发送的流程
  1. client 端创建得到一个 BpxxService,会调用BpxxService 实现的接口函数(比如 helloworld);它会将str参数打包到Parcel 对象中,然后调用remote()->transact(xxx)
  2. remote() 是在BpXXXService的父类 BpRefBase 中实现的,返回的就是一个BpBinder,实际上调用的就是BpBinder 的transact()函数
  3. BpBinder 的transact实现,就是直接通过IPCThreadState::self()->transact()发送数据
  • service 端接收Client 端的请求
  1. 通过IPCThreadState接收到client的请求后,首先会调用BBinder的transact方法
  2. BBinder的transact方法又会调用子类实现的虚拟方法onTransact,这个虚拟方法是在BnXXXService中实现的
  3. onTransact方法,会通过传递进来的参数来判断,需要调用IXXXService中的那个方法,示例中只有一个helloWorld方法
  4. 直接调用helloWorld,就会找到它的真正实现,也就是BnXXXService的子类XXXService中的helloWorld方法

总结一下:BpBinder并不在继承关系当中,它只是一个打包数据,并通过IPCThreadState::self()->transact()方法发送出去,而BBinder和BnXXXService的作用,就是接收IPCThreadState传递过来的信息,解包数据并调用XXXService真正的实现

Binder 源代码路径:/frameworks/native/libs/binder
Binder 类的继承关系图如下:


interface_binder.jpg
基础 Native层 Binder demo

新建IMyService.h 和 IMyService.cpp,其中主要定义BnMyService 和 BpMyService类(p表示 proxy 是客户端使用的对象,n 表示 native,是server 端使用的对象)
IMyService.h

#ifdef _MYSERVICE_H
#define _MYSERVICE_H

#include <utils/RefBase.h>
#include <utils/Error.h>
#include <utils/String16.h>
#include <binder/IIterface.h>
#include <binder/Parcel.h>

namespace android {
class IMyService:public IInterface {
public:
    DECLARE_META_INTERFACE(MyService);
    virtual void demoInterface() = 0;

}

enum {
    DEMOINTERFACE = 1;
};

class BpMyService:public BpInterface<IMyService> {
public:
    explicit BpMyService(const sp<IBinder>& impl);
    virtual ~BpMyService();
    virtual void demoInterface();
};

class BnMyService: public BnInterface<IMyService> {
public:
    virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
    inline BnMyService() {};
    virtual void demoInterface();

};

}
#endif

IMyService.cpp

#define LOG_TAG "IMyService"

namespace android {

IMPLEMENT_META_INTERFACE(MyService,"android.demo.IMyService");

BpMyService::BpMyService(const sp<IBinder>& impl):BpInterface<IMyService>(impl) {

}

void BpMyService::demoInterface() {
        Parcel data, reply;
        data.writeInterfaceToken(IMyService::getInterfaceDescriptor());
        remote()->transact(DEMOINTERFACE, data, &reply);
        std::cout << "get num from BnMyService" << reply.readInt32() << std::endl;
}

status_t BnMyService::onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags) {
    flags = 0;
    switch(code) {
     case DEMOINTERFACE:
        cout << "BnMyService:: onTransact... " << endl;
        CHECK_INTERFACE(IMyService, data, reply);
        demoInterface();
        reply->writeInt32(2015);
        return NO_ERROR;
        break;
    default:
        break;
    }
    return NO_ERROR;
}
void BnMyService::demoInterface() {
    cout << "BnMyService:: demoInterface" << endl;
}

}

定义的 BpMyService 类和 BnMyService类都继承了 IMyService类,继承方式采用android binder 定义的模板:

class BpMyService: public  BpInterface<IMyService>
class BnMyService: public  BnInterface<IMyService> 

BpInterface 是定义和实例化后的代码如下:

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
    explicit                    BpInterface(const sp<IBinder>& remote);
protected:
    virtual IBinder*            onAsBinder();
};

实例化之后的类:
class BpInterface : public IMyService, public BpRefBase
{
public:
    explicit                    BpInterface(const sp<IBinder>& remote);
protected:
    virtual IBinder*            onAsBinder();
};

BpMyService::demoInterface() 中使用的remote() 函数就是在 BpRefBase中定义的,是一个IBinder 类型的指针,是从ServiceManager getService 获取到的,本质上就是一个BpBinder对象
IBinder* const mRemote;

在定义 IMyService 类中,还有两个重要的宏:

DECLARE_META_INTERFACE(IMyService);
IMPLEMENT_META_INTERFACE(INTERFACE, NAME) ;

宏展开后的形式:
#define DECLARE_META_INTERFACE()                              
    static const String16 descriptor;                       
    static android::sp<IMyService> asInterface(sp<:IBinder>& obj);             
    virtual const String16& getInterfaceDescriptor() const; 
    IMyService();                                                   
    virtual ~IMyService();          

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

这里用这两个宏简化了 IMyService 类的定义,其中有两个重要的成员

  • getInterfaceDescriptor 可以获取到binder 传输需要使用的 Token Descriptor
  • asInterface 函数返回BpMyService 对象
Binder 中关键类解析
IBinder

IBinder也是一个抽象类,它包括了localBinder(), remoteBinder()和transact()等非常重要的接口;IBinder有两个直接子类类:BpBinder和BBinder

class IBinder : public virtual RefBase {

    /**
     * Check if this IBinder implements the interface named by
     * @a descriptor.  If it does, the base pointer to it is returned,
     * which you can safely static_cast<> to the concrete C++ interface.
     */
    virtual sp<IInterface>  queryLocalInterface(const String16& descriptor);
    ......

    virtual status_t        transact(   uint32_t code,
                                        const Parcel& data,
                                        Parcel* reply,
                                        uint32_t flags = 0) = 0;
   .....
    virtual BBinder*        localBinder();
    virtual BpBinder*       remoteBinder();
}

BpBinder和BBinder
BpBinder 对象

BpBinder:是Binder代理类,通过remoteBinder()可以获取BpBinder对象;
BpBinder的事务接口transact()会调用 IPCThreadState的transact(),进而实现与Binder驱动的事务交互
BpBinder中有一个mHandle句柄成员,用于保存server 位于Binder 驱动中 Binder 引用的描述,Handle = 0 就是ServiceManager 的handle

status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

BpBinder* BpBinder::remoteBinder()
{
    return this;
}

inline  int32_t     handle() const { return mHandle; }

BBinder对象

BBinder:Servier 端的Binder 对象,通过localBinder()可以获取BBinder对象,当Server收到请求之后,会调用BBinder的onTransact()函数进行处理。而不同的Server会重载onTransact()函数,从而可以根据各自的情况对事务进行处理

BBinder* BBinder::localBinder()
{
    return this;
}

class BBinder : public IBinder
{
public:
    BBinder();

    virtual const String16& getInterfaceDescriptor() const;
    virtual bool        isBinderAlive() const;
    virtual status_t    pingBinder();
    ...

    virtual status_t    transact(   uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
    ...

    virtual BBinder*    localBinder();

protected:
    virtual             ~BBinder();
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);

private:
      BBinder(const BBinder& o);
    ...
};

RefBase和BpRefBase

RefBase:使用andoid 智能指针必须继承的基础类,包含了智能指针的引用计数
BpRefBase:
BpRefBase继承于RefBase,它有一个IBinder*类型的成员mRemote,同时提供了获取该mRemote的方法。实际上,该mRemote就是BpBinder对象

class BpRefBase : public virtual RefBase
{
protected:
    explicit                BpRefBase(const sp<IBinder>& o);
    virtual                 ~BpRefBase();
    virtual void            onFirstRef();
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);

    inline  IBinder*        remote()                { return mRemote; }
    inline  IBinder*        remote() const          { return mRemote; }

private:
                            BpRefBase(const BpRefBase& o);
    BpRefBase&              operator=(const BpRefBase& o);

    IBinder* const          mRemote;
    RefBase::weakref_type*  mRefs;
    std::atomic<int32_t>    mState;
};
IInterface 和 interface_cast

IInterface 定义在frameworks/native/include/binder/IInterface.h中,和RefBase类似,它也是一个公共父类,IInterface中声明了asBinder()方法,用于获取对象的IBinder对象。

class IInterface : public virtual RefBase
{
public:
    IInterface();
    static sp<IBinder>  asBinder(const IInterface*);
    static sp<IBinder>  asBinder(const sp<IInterface>&);

protected:
    virtual                     ~IInterface();
    virtual IBinder*            onAsBinder() = 0;
};

onAsBinder函数在 IInterface 的父类 BpMyService 和 BnMyService 中实现,具体是在 BnInterface 和 BpInterface 的模板中实现:

interface_cast 是一个模板函数,本质上就是调用 asInterface 接口,在IMyService 的实现中,返回就是BpMyService的对象;

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}
IMyService.cpp
    sp<IMyService> IMyService::asInterface(              
            const sp<IBinder>& obj)               
    {                                                                   
        sp<IMyService> intr;                               
        if (obj != NULL) {                                              
            intr = static_cast<IMyService*>(                          
                obj->queryLocalInterface(                              
                        IMyService::descriptor).get());               
            if (intr == NULL) {                                         
                intr = new BpMyService(obj);                          
            }                                                           
        }                                                               
        return intr;                                                    
    } 
BpInterface 和 BnInterface
  • BpInterface:它定义在frameworks/native/include/binder/IInterface.h中;BpInterface是一个模板类,同时继承了BpRefBase和INTERFACE,这里的INTERFACE是模板,像IServiceManager,IMediaPlayerService,IMyService

  • BnInterface:它定义在frameworks/native/include/binder/IInterface.h中,和BpInterface类似,BnInterface也是一个模板类,它同时继承了BBinder和INTERFACE;像BnServiceManager,BnMediaPlayerService,BnMyService

相关文章

网友评论

      本文标题:Android 基础学习(4) ---- Binder 简要原理

      本文链接:https://www.haomeiwen.com/subject/fpdbxdtx.html