interface_cast简介

Android  源码分析  2023年6月14日 pm6:18发布1年前 (2023)更新 城堡大人
83 0 0

前言

interface_castAndroid Framework中很常见,虽然记得住,但也容易忘记,因此记录一下,方便自己查阅。

正文

这里以IServiceManager.cpp为例。

IServiceManager.cpp

目录:\frameworks\native\libs\binder\IServiceManager.cpp
// IServiceManager.cpp
//单例模式
sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            //1. gDefaultServiceManager是谁的对象?
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    return gDefaultServiceManager;
}

从上面interface_cast()转换后,gDefaultServiceManager是谁的对象?是不是很好奇!

这里提前剧透:

gDefaultServiceManager是BpServiceManager的对象!

具体怎么来的,就需要知道interface_cast的作用。

引用的头文件

#include <binder/IInterface.h>

IInterface.h

目录:\frameworks\native\include\binder\IInterface.h
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

模板类,继续看asInterface()

// ----------------------------------------------------------------------
//接口声明
#define DECLARE_META_INTERFACE(INTERFACE)                               \
    static const ::android::String16 descriptor;                        \
    static ::android::sp<I##INTERFACE> asInterface(                     \
            const ::android::sp<::android::IBinder>& obj);              \
    virtual const ::android::String16& getInterfaceDescriptor() const;  \
    I##INTERFACE();                                                     \
    virtual ~I##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;                                \
    }                                                                   \
    //重点 start
    ::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);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    //重点 end
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \
#define CHECK_INTERFACE(interface, data, reply)                         \
    if (!(data).checkInterface(this)) { return PERMISSION_DENIED; }     \
// ----------------------------------------------------------------------

主要看接口实现部分。如果看明白了

interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));

就知道为啥返回的是BpServiceManager的对象!

翻译一下上面重点部分

PS: 把INTERFACE替换一下即可。

::android::sp<IServiceManager> IServiceManager::asInterface(
        const ::android::sp<::android::IBinder>& obj) 
{                                                     
    ::android::sp<IServiceManager> intr;                 
    if (obj != NULL) {                                
        intr = static_cast<IServiceManager*>(            
            obj->queryLocalInterface(                 
                    IServiceManager::descriptor).get()); 
        if (intr == NULL) {                           
            intr = new BpServiceManager(obj); //看这里          
        }                                             
    }                                                 
    return intr;                                      
}    

从上面就是可以知道,gDefaultServiceManager就是BpServiceManager对象。

参考文章

  1. interface_cast 的使用举例

  2. Binder系列5—注册服务(addService)

 历史上的今天

  1. 2021: 鲁迅 :秋夜(0条评论)
  2. 2021: 汪曾祺:端午的鸭蛋(0条评论)
  3. 2018: Launcher2分析之布局(0条评论)
  4. 2018: grep的命令的部分使用(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

韩少功:偷书

我当年就读的中学,有一中型的图书馆。我那时不大会看书,只是常常利用午休时间去那里翻翻杂志。《世界知识》上有很多好看的彩色照片。一种航空杂志也曾让我浮想连翩。文革开始,这个图书馆照例关闭,因受到媒体批判的“毒草”越来越多,图书馆疲于清理和下架,只好一关了之。类似的情况是,城里各大书店也立刻空空荡荡,...

Android setSystemUiVisibility详解

简介下面是setSystemUiVisibility可以设置的一部分flagSYSTEM_UI_FLAG_LOW_PROFILE 弱化状态栏和导航栏的图标SYSTEM_UI_FLAG_HIDE_NAVIGATION 隐藏导航栏,用户点击屏幕会显示导航栏SYSTEM_UI_FLAG_FUL...

Android静态换肤-日夜主题切换之不继承Activity

前言记录一下,有Activity换肤之日夜主题无缝切换。一般来说,换肤分为静态换肤和动态换肤,Android的日夜模式可以看做静态换肤的一种。是以资源存放位置来说的,其实不是很严谨,但换肤的本质都是一样的。正文Android高版本都支持日夜模式切换,资源放在对应日夜目录,比如//有...

Android消息机制之一基础简介(1)

在项目中,使用Handler是比较多的,延迟处理信息啊,或者跨线程刷新UI界面啊等.用大家都会用,但要用好,或许只能多看看源码和跟大牛们学习学习了.Handler.java,Looper.java,Message.java,MessageQueue.java这几个类主要是在/frameworks/...

Kotlin中的特殊函数简介

前言简单记录一下Kotlin中的run()、apply()、let()、also()和with()等特殊的函数,方便自己查阅。正文run()@kotlin.internal.InlineOnlypublic inline fun <T, R> T.run(block: T....

Android图片旋转+倒影

前言根据前面两篇文章,这里进行组合也就是倒影+旋转,顺便加上了倒影渐变。效果如图。正文直接上代码<!-- layout_height= 倒影高度+分割线高度+图片高度,否则显示不全 -->​<com.biumall.reflectview.view.Rotat...