zoukankan      html  css  js  c++  java
  • android binder IPC 通信中 asInterface 与 asBinder

    Binder 用于通信,Interface用于功能调用。

    其实asInterface 完成的是Binder到Interface的转换,具体就是:

    BBinder->BnInterface

    BpBinder->BpInterface

    而asBinder功能则相反,具体是:

    BnInterface->BBinder

    BpInterface->BpBinder

    asInterface 与 asBinder 的返回值与输入参数和调用对象有关,如下:

    template<typename INTERFACE>
    IBinder* BnInterface<INTERFACE>::onAsBinder()
    {
        return this;
    }
    
    template<typename INTERFACE>
    inline IBinder* BpInterface<INTERFACE>::onAsBinder()
    {
        return remote();
    }
    
    sp<IXxx>asInterface( const sp<IBinder>& obj)   
     {                                                           
            sp<IXxx> intr;                       
            if (obj != NULL) {                                             
                intr = static_cast<IXxx*>(obj->queryLocalInterface(descriptor).get());            
                if (intr == NULL) {                                       
                    intr = new BpIXxx(obj);                       
                }                                                         
            }                                                             
            return intr;                                                  
    }      

    1、调用由 继承自BnInterface的类 实例化的对象,返回对象本身,因为本来就该类本来就继承自 BBinder。

    2、调用由 继承自BpInterface的类 实例化的对象,返回的是BpBinder。

    3、调用 asInterface 时,如果传入的是 继承自BBinder的类 实例化的对象,返回的是BnInterface。

    4、调用 asInterface 时,如果传入的是 继承自BpBinder的类 实例化的对象,返回的是BpInterface。

    ======================================================================================

    使用情景之一:从 A 服务中获取 Xxx 服务,IXxx 继承自 IInterface。

    A server 建立 BnInterface,A client 获得 BpInterface,而 BpBinder 和 BBinder 扮演信使的作用。

    在 client 端使用某个功能时,一般用 IXxx->Func() 的形式,那么如何得到 IXxx呢?

    1、通过 A 的 client 向 A 的 server 发送 GET_XXX 命令

    IA->remote()->transact(GET_XXX, data, &reply);

    其中 IA->remote() 返回的 A 的 BpBinder。

    2、A 的 server 通过 A 的 BBinder 收到 GET_XXX 命令

    调用 BnA 的 onTransact

    status_t BnA::onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
         switch(code) {
            case GET_XXX: {
                CHECK_INTERFACE(IXxx, data, reply);
                sp<IXxx> x = createXxx();
                reply->writeStrongBinder(x->asBinder());
                return NO_ERROR;
            } break;
            default:
                return BBinder::onTransact(code, data, reply, flags);
        }
    }

    createXxx() 返回的是 new 出来的 Xxx 对象,而 Xxx 在此处代表一个BnInterface

    3、reply->writeStrongBinder(x->asBinder())

    asBinder 在 BnInterface 中实现

    template<typename INTERFACE>
    IBinder* BnInterface<INTERFACE>::onAsBinder()
    {
        return this;
    }

    即返回的是自身,因为 BnInterface 同时是一个 BBinder。

    reply->writeStrongBinder 调用 Binder 驱动,Binder 驱动将BBinder的引用返回给 client。

    4、reply.readStrongBinder()

    reply.readStrongBinder() 返回的是 BBinder 的代理对象 BpBinder

    return interface_cast<IXxx>(reply.readStrongBinder());

    5、interface_cast<IXxx>

    interface_cast 展开

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

    将 BpBinder 转为 IXxx,也就是 BpInterface。

    至此得到了与 Xxx server 有关联的 IXxx,当然,实际上建立的 BpXxx 与 BnXxx 之间的通信。

  • 相关阅读:
    Javascript绝句欣赏
    【转载】浏览器的工作原理:新式网络浏览器幕后揭秘
    从零开始编写自己的JavaScript框架(二)
    从零开始编写自己的JavaScript框架(一)
    CSS 编码中超级有用的工具集合
    创建简单的响应式HTML5模版
    Javascript中的垃圾回收机制
    JavaScript继承详解(五)
    线上应用接入sentinel的第一个流控规则
    sentinel控制台监控数据持久化【MySQL】
  • 原文地址:https://www.cnblogs.com/JonnyLulu/p/3757452.html
Copyright © 2011-2022 走看看