美文网首页
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