研究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 中 unable to start service 错误解决方法
  2. Android之Servic的生命周期和调用方法
  3. Android中fragment A里面点击button跳转到fragment B实现方法
  4. Android Activity之间传递图片(Bitmap)的方法
  5. 【android】ORMLite框架 的使用方法---给你的数据库操作插上翅膀
  6. Android错误解决方法大集合
  7. Android中WebView获取网页中标题 ,内容, 图片的方法
  8. Android获取IPV4的方法

随机推荐

  1. Android锁屏状态下弹出activity,如新版qq
  2. Android(安卓)使用setContentView来实现A
  3. Android2.2添加Ethernet 框架支持(一)
  4. Android(安卓)获取屏幕的分辨率
  5. 日拱一卒(五十六)
  6. Android(安卓)Gallery通过按钮控制选择
  7. 知识点整理(三)易错记录
  8. Android(安卓)如何根据网络地址获取网络
  9. Android(安卓)Studio 首次创建工程下载Gr
  10. Android的提交数据到服务器