研究Android底层代码时,尤其是Binder跨进程通信时,经常会发现interface_cast和asBinder,很容易被这两个函数绕晕,下面通过分析源码来讲解一下:

interface_cast

下面根据下述ICameraClient例子进行分析一下:

//伪代码sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(BpBinder(handle));

看下interface_cast的实现,其代码在IInterface.h中

template<typename INTERFACE>inline sp interface_cast(const sp& obj){    return INTERFACE::asInterface(obj);}//这是一个模板函数,展开即为:inline sp interface_cast(const sp& obj){    return ICameraClient ::asInterface(obj);}

那ICameraClient的asInterface在哪实现的呢?发现找了ICameraClient.h和ICameraClient.cpp只有下面两个定义:

//frameworks/av/include/camera/android/hardware/ICameraClient.hDECLARE_META_INTERFACE(CameraClient);//frameworks/av/camera/ICameraClient.cppIMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient");

DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE函数是其父类IInterface(frameworks\native\include\binder\IInterace.h)的宏定义:

//声明asInterface函数#define DECLARE_META_INTERFACE(INTERFACE)    static const android::String16 descriptor;    //声明asInterface函数    static android::sp##INTERFACE> asInterface(             const android::sp& obj);    virtual const android::String16& getInterfaceDescriptor() const;    I##INTERFACE();    virtual ~I##INTERFACE();展开为:#define DECLARE_META_INTERFACE(CameraClient)    //增加一个描述符    static const android::String16 descriptor;    //声明asInterface函数    static android::sp asInterface(             const android::sp& obj);    //获取描述符函数    virtual const android::String16& getInterfaceDescriptor() const;    //构造函数以及折构函数    ICameraClient();    virtual ~ICameraClient();//实现asInterface函数#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##INTERFACE> I##INTERFACE::asInterface(            const android::sp& obj)    {        android::sp##INTERFACE> intr;         if (obj != NULL) {            intr = static_cast##INTERFACE*>(                obj->queryLocalInterface(                         I##INTERFACE::descriptor).get());             if (intr == NULL) {                intr = new Bp##INTERFACE(obj); //展开即为intr = new BpServiceManager(obj);            }        }        return intr;    }    I##INTERFACE::I##INTERFACE() { }    I##INTERFACE::~I##INTERFACE() { }展开为:#define IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient")    //定义ICameraClient的描述符为"android.hardware.ICameraClient"    const android::String16 ICameraClient ::descriptor("android.hardware.ICameraClient");     //获取描述符"android.hardware.ICameraClient"    const android::String16&             ICameraClient ::getInterfaceDescriptor() const {         return ICameraClient ::descriptor;     }                            //实现asInterface函数    android::sp ICameraClient::asInterface(            const android::sp& obj)    {        android::sp intr;         if (obj != NULL) {            intr = static_cast(                //queryLocalInterface是在IBinder中定义的,默认返回NULL,但在BBinder的子类BnInterface中,重载了该方法,返回this,而BpBinder没有重载,使用IBinder的默认实现,返回NULL                obj->queryLocalInterface(                         ICameraClient::descriptor).get());             if (intr == NULL) {                //构建INTERFACE的Bp端代理对象                intr = new BpCameraClient(obj);            }        }        return intr;    }    ICameraClient::ICameraClient() { }    ICameraClient::~ICameraClient() { }

总结一下, 如果interface_cast的参数obj是BnInterface,则返回其自身,如果参数obj是BpInterface,则new一个Bp代理对象并返回。这里我们用的是ICameraClient例子来讲解的,则返回BpCameraClient,别的接口也是同样分析的,比如IServiceManager,也会有类似声明如下,则返回BpServiceManager。

//frameworks\native\include\binder\IServiceManager.hDECLARE_META_INTERFACE(ServiceManager);//frameworks\native\libs\binder\IServiceManager.cppIMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

asBinder

接着使用上面ICameraClient例子进行分析一下:

//伪代码,根据interface_cast的分析,知道cameraClient即为BpCameraClient(BpBinder(handle))sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());IInterface::asBinder(cameraClient);

看下asBinder的方法,在IInterface.cpp中

sp IInterface::asBinder(const IInterface* iface){    if (iface == NULL) return NULL;    return const_cast(iface)->onAsBinder();}sp IInterface::asBinder(const sp& iface){    if (iface == NULL) return NULL;    return iface->onAsBinder();}

都会走到onAsBinder方法

BnInterface

BnInterface的onAsBinder方法,直接返回自身,因为BnInterface继承自BBinder,而BBinder又继承自IBinder

template<typename INTERFACE>IBinder* BnInterface::onAsBinder(){    return this;}根据例子展开为:template<typename ICameraClient>IBinder* BnInterface::onAsBinder(){    return this;}

BpInterface

BpInterface的onAsBinder方法,调用remote()方法并返回

template<typename INTERFACE>inline IBinder* BpInterface::onAsBinder(){    return remote();}根据例子展开为:template<typename ICameraClient >inline IBinder* BpInterface::onAsBinder(){    return remote();}

remote()方法在其父类BpRefBase中实现,就是返回mRemote变量

inline  IBinder*        remote()                { return mRemote; }

而mRemote变量是在创建BpInterface对象时,将remote变量传给了其父类BpRefBase,我们这个例子里面remote就是BpBinder(handle)

template
inline BpInterface::BpInterface(const sp& remote)
: BpRefBase(remote)
{
}

BpRefBase::BpRefBase(const sp& o)
: mRemote(o.get()), mRefs(NULL), mState(0)
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);

if (mRemote) {    mRemote->incStrong(this);           // Removed on first IncStrong().    mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.}

}
“`

总结一下, 如果asBinder的参数iface是BnInterface类型,则返回其自身,如果参数iface是BpInterface类型,则返回其mRemote远程代理对象BpBinder(handle) 。

作者:lb377463323
出处:http://blog.csdn.net/lb377463323
原文链接:http://blog.csdn.net/lb377463323/article/details/78385845
转载请注明出处!

更多相关文章

  1. 【Android】从无到有:手把手一步步教你使用最简单的 Fragment(一)
  2. Android(安卓)Binder简介
  3. Android中AppWidget加载流程(一)
  4. Android(安卓)之 ServiceManager与服务管理
  5. Android(安卓)混合了 JSON 的 Android(安卓)应用程序
  6. 浅谈Java中Collections.sort对List排序的两种方法
  7. 箭头函数的基础使用
  8. Python技巧匿名函数、回调函数和高阶函数
  9. Python list sort方法的具体使用

随机推荐

  1. Android(安卓)URL 下载文件
  2. [Android] 获取设备的APP信息
  3. android 禁用解锁
  4. Android(安卓)dip与px转换时的公式加0.5
  5. [Android]Unlock SIMLOCK
  6. Android计时器
  7. [置顶] android webview and javascript
  8. android读取原始的xml文件
  9. android FragmentPagerAdapter的“标准”
  10. 【Android策略决】Fragment实例化及通过s