文档章节

Android Binder机制 - interface_cast和asBinder讲解

天王盖地虎626
 天王盖地虎626
发布于 02/27 05:57
字数 1000
阅读 149
收藏 0

 
研究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> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}
//这是一个模板函数,展开即为:
inline sp<ICameraClient > interface_cast(const sp<IBinder>& obj)
{
    return ICameraClient ::asInterface(obj);
}
那ICameraClient的asInterface在哪实现的呢?发现找了ICameraClient.h和ICameraClient.cpp只有下面两个定义:

//frameworks/av/include/camera/android/hardware/ICameraClient.h
DECLARE_META_INTERFACE(CameraClient);

//frameworks/av/camera/ICameraClient.cpp
IMPLEMENT_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<I##INTERFACE> asInterface( 
            const android::sp<android::IBinder>& 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<ICameraClient> asInterface( 
            const android::sp<android::IBinder>& 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<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); //展开即为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> ICameraClient::asInterface(
            const android::sp<android::IBinder>& obj)
    {
        android::sp<ICameraClient> intr; 
        if (obj != NULL) {
            intr = static_cast<ICameraClient*>(
                //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.h
DECLARE_META_INTERFACE(ServiceManager);

//frameworks\native\libs\binder\IServiceManager.cpp
IMPLEMENT_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<IBinder> IInterface::asBinder(const IInterface* iface)
{
    if (iface == NULL) return NULL;
    return const_cast<IInterface*>(iface)->onAsBinder();
}

sp<IBinder> IInterface::asBinder(const sp<IInterface>& iface)
{
    if (iface == NULL) return NULL;
    return iface->onAsBinder();
}
都会走到onAsBinder方法

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

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

根据例子展开为:
template<typename ICameraClient>
IBinder* BnInterface<ICameraClient>::onAsBinder()
{
    return this;
}
BpInterface
BpInterface的onAsBinder方法,调用remote()方法并返回

template<typename INTERFACE>
inline IBinder* BpInterface<INTERFACE>::onAsBinder()
{
    return remote();
}

根据例子展开为:
template<typename ICameraClient >
inline IBinder* BpInterface<ICameraClient>::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) 。

本文转载自:http://www.voidcn.com/article/p-xatridva-bqp.html

天王盖地虎626

天王盖地虎626

粉丝 39
博文 673
码字总数 23458
作品 0
南京
私信 提问
加载中

评论(0)

android的binder机制研究(C++部分)

(一) 概述 android的binder机制提供一种进程间通信的方法,使一个进程可以以类似远程过程调用的形式调用另一个进程所提供的功能。binder机制在Java环境和C/C++环境都有提供。 android的代码...

eric_zhang
2011/07/20
5.4K
1
Android Binder原理(二)ServiceManager中的Binder机制

关联系列 Android AOSP基础系列 Android系统启动系列 应用进程启动系列 Android深入四大组件系列 Android深入理解Context系列 Android深入理解JNI系列 Android解析WindowManager Android解析...

刘望舒
2019/11/08
0
0
Android跨进程通信:图文详解 Binder机制 原理

前言 如果你接触过 跨进程通信 (IPC),那么你对Binder一定不陌生 虽然 网上有很多介绍 Binder的文章,可是存在一些问题:浅显的讨论Binder机制 或 一味讲解 Binder源码、逻辑不清楚,最终导...

天王盖地虎626
2018/12/21
49
0
Android深入浅出之Binder机制

Android深入浅出之Binder机制 一 说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度...

z.net
2013/06/25
133
0
一起来聊聊Android基础之Binder的使用

Binder实现了IBinder接口,通常我们不会直接去实现Binder,而是通过aidl工具来定义接口,自动生成相应的Binder的子类。 从Android Framework角度来说,Binder是ServiceManager连接各种Manag...

天王盖地虎626
2019/06/05
7
0

没有更多内容

加载失败,请刷新页面

加载更多

复习下Linux去除重复项命令uniq

uniq也是linux管道命令家族中的一员,其主要功能是去除重复项。 在介绍uniq命令之前,我们先来新建在下面的案例中需要用到的文件/tmp/uniq.txt,内容如下:默认情况下uniq只会检索相邻的重复...

php开源社区
25分钟前
17
0
展会人脸识别签到门禁闸机,“快”“准”识别“刷脸”签到

结合客户需求自主研发动态人脸识别身份核查系统。集现场人脸采集、身份验证、黑名单预警、等功能为一体,从读取身份信息到现场采集人脸照片、进行比对、并获取结果,全程自动化,需增加外围硬...

艾力奋会展服务
27分钟前
17
0
mysql索引原则

设计原则 经常被用户条件查询的字段,创建索引 索引不是越多越好;索引占用磁盘空间,影响insert、update、delete性能 经常修改的表,不要建过多的索引;更新表数据时,索引也会进行微调或者...

简到珍
29分钟前
15
0
排序算法(快排&归并&选择&插入&冒泡)-php&go实现

PHP //排序常用算法//排序算法 稳定排序算法class SortAlg{ //冒泡排序 public function maoPaoSort($arr) { $n = count($arr); if ($n <= 1) { ......

山人有妙计
30分钟前
15
0
基于函数计算的 BFF 架构

什么是 BFF BFF 全称是 Backends For Frontends (服务于前端的后端),起源于 2015 年 Sam Newman 一篇博客文章《Pattern: Backends For Frontends —— Single-purpose Edge Services for U......

阿里巴巴云原生
35分钟前
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部