interface_cast简介

Android  源码分析  2023年6月14日 pm6:18发布1年前 (2023)更新 91es.com站长
44 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、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

UML类图中属性的可见性简介

UML类图中属性的可见性分为4级public 公用的 :用+ 前缀表示 ,该属性对所有类可见protected 受保护的:用 #  前缀表示,对该类的子孙可见private 私有的:用- 前缀表示,只对该类本身可见package 包的:用 ~ 前缀表示,只对同一包声明的其他类可见...

TextView设置倾斜右边显示不全

直接上布局代码 <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@an...

Launcher根据包名启动应用

前言很多项目中Launcher是有可能自定义的,毕竟Android原生的Launcher比较庞大,有时候需要的需求很简单,自己重新写Launcher也比较容易维护。为啥要根据包名启动,因为一个应用可能存在多个Activity,当按Home键退出后,再次从Launcher界面点击需要回到之前展示...

pengdingIntent的使用

什么是pengdingIntent?pendingIntent字面意义:等待的,未决定的Intent。要得到一个pendingIntent对象,使用方法类的静态方法getActivity(Context, int, Intent, int)getBroadcast(Context, int...

拦截并统一处理Activity的KeyEvent事件简介

前言本文介绍的是在Activity中对所有的事件进行统一拦截处理。下面是简单的需求:当上下左右按键操作界面的按键(可以点击的View)已经滑到最后一个或者第一个时,需要发信息通知。比当滑到列表底部时,此时就需要触发消息出去,至于发给谁这里暂定。正文隐藏内容!付费阅读后才能查看!¥1 ¥...

《MySQL基础教程》笔记4

前言本文主要是select语句的使用学习一下MySQL,一直没有系统的学习一下。最近有空,看了《MySQL基础教程-西泽梦路》,简单的做一下笔记。记录于此,方便自己回忆。MySQL中对大小写没有区分,我这里习惯性用小些。正文我这以Window版的phpstudy软件验证。需要进入...