C++ Binder机制学习(转载)

作者: llm_5243 | 来源:发表于2020-03-26 13:56 被阅读0次

    核心内容

    Binder机制的核心实际上和Android中的Handler发送消息的机制很像,在Binder中负责发消息的是继承了BpInterface的子类,负责处理消息的是BnInterface的子类

    发送消息的具体函数是

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

    处理消息的具体函数是

    status_t onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)
    

    基础知识

    BpInterface和BpBinder中的p表示的意思就是proxy,表示中间的调用和代理,不会具体实现功能
    BnInterface和BBinder中的n表示的意思就是native 是最终实现的地方
    BpBinder类由client来继承,当然,如果用不上的话,也可以不用继承
    如果一个类想使用android中的智能指针,就必须继承或者间接继承RefBase类,比如client

    继承关系

    定义一个接口类IDemo,继承IInterface
    定义一个BpDemoService类,继承BpInterface<IDemo>
    定义一个BnDemoService类,继承BnInterface<IDemo>
    定义一个DemoService类,继承BnDemoService,用来实现具体的函数
    定义一个接口类IDemo,继承IInterface,里面只有一个函数

    class IDemo :public IInterface
    {
        public:
            virtual int getAge();
    }
    

    定义一个BpDemoService类,继承BpInterface

    enum
    {
        CUSTOM_CODE = IBinder::FIRST_CALL_TRANSACTION
    };
    class BpDemoService: public BnInterface<IDemo>
    {
        public:
            BpDemoService(const sp<IBinder>& impl):BpInterface<IDemo> (impl){};
            virtual BOOL getAge()
            {
                Parcel data, reply;
                data.writeInterfaceToken(IDemo::getInterfaceDescriptor());
                remote()->transact(CUSTOM_CODE, data, &reply);
                return (BOOL)reply.readInt32();
            }
    }
    

    定义一个BnDemoService类,继承BnInterface

    class BnDemoService: public BnInterface<IDemo>
    {
        public:
            virtual status_t onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags= 0 );
    };
    
    status_t BnDemoService::onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)
    {
        switch(code)
            {
                case CUSTOM_CODE:
                    {
                        CHECK_INTERFACE(IDemo,data,reply);
                        int res = getAge();
                        reply->writeInt32((int32_t)res);
                        return NO_ERROR;
                    }
                    break;
                default:
                    break;
           }
        return BBinder::onTransact(code, data, reply, flags);
    }
    

    定义一个Service类,继承BnDemoService
    用来具体实现函数,最后记得别忘了调用IMPLEMENT_META_INTERFACE宏来进行注册

    class DemoService : public BnDemoService,public BinderService<DemoService>
    {
        public:
            int getAge();
    }
    IMPLEMENT_META_INTERFACE(DemoService, "demo.service");
    

    调用顺序

    在client端调用的时候,首先获取ServiceManager
    然后创建一个binder用来装载service
    使用interface_cast()来获得对应的代理端
    通过代理端调用在service中实现的函数

    sp < IServiceManager > sm = defaultServiceManager();
    sp < IBinder > binder;
    binder = sm->getService(String16("demo.service"));
    sp<IDemo> m_pDemoService;
    m_pDemoService = interface_cast<IDemo> (binder);
    m_pDemoService->getAge();
    

    重点函数

    interface_cast()函数
    作用是把从getService获取到的Binder强制转换为IInterface的子类,也就是定义了自己的那些接口的类
    函数原型

    template<typename INTERFACE>
    inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
    {
        return INTERFACE::asInterface(obj);
    }
    

    asInterface这个函数是IMPLEMENT_META_INTERFACE宏中进行定义的。具体可以参考

    #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<android::IBinder>& 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);/* IMPORTENT */           \
                }                                                           \
            }                                                               \
            return intr;                                                    \
        }                                                                   \
        I##INTERFACE::I##INTERFACE() { }                                    \
        I##INTERFACE::~I##INTERFACE() { }         
    

    也就是说interface_cast函数最后返回的实际上是new BpDemoService(binder);

    remote()->transact()函数
    位置是在代理类中调用的,用来远程给onTransact函数发送消息和数据的,类似于handler.sendMessage()
    函数原型

    status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    1
    onTransact()函数
    这个函数的位置是在实现类(实现BnInterface)中的,相当于hander中的handleMessage函数

    函数原型

    virtual status_t onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags= 0 );
    ————————————————
    版权声明:本文为CSDN博主「二仪式」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/u013894427/article/details/83870059

    相关文章

      网友评论

        本文标题:C++ Binder机制学习(转载)

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