关于Context和ContextImpl还有ContextWrapper的关系

关于Context和ContextImpl还有ContextWrapper的关系

1.Context和ContextImpl还有ContextWrapper的关系

img

​ 图一.Context和ContextImpl还有ContextWrapper的关系示意图

1.1.ContextImpl是Context的实现类

从Context和ContextImpl的源代码中,可以看出Context是一个抽象类,具体的实现类是ContextImpl

public abstract class Context {

Context.java文件

class ContextImpl extends Context {....}

ContextImpl.java文件

1.2.ContextWrapper是Context的包装类

从ContextWrapper的源代码可以看出,ContextWrapper继承自Context; 并且ContextWrapper类持有Context的引用;

所以最终是要通过java的多态这个属性,调用Context类的相关方法,实际上是调用ContextImpl类里面的方法

public class ContextWrapper extends Context {@UnsupportedAppUsageContext mBase;

ContextWrapper.java文件

2.ContextImpl跟ContextWrapper的关联过程

2.1.ContextWrapper可以关联的可能入口

根据下面的ContextWrapper的源码的解读,如果ContextWrapper关联ContextImpl,

只有两个地方可以把Context作为参数传进来

第一个:ContextWrapper的构造函数

第二个:attachBaseContext函数

这两个函数都会把context 赋值给名字为mBase的Context的属性

public class ContextWrapper extends Context {@UnsupportedAppUsageContext mBase;@GuardedBy("mLock")@VisibleForTestingpublic List<ComponentCallbacks> mCallbacksRegisteredToSuper;private final Object mLock = new Object();public ContextWrapper(Context base) {mBase = base;}protected void attachBaseContext(Context base) {if (mBase != null) {throw new IllegalStateException("Base context already set");}mBase = base;}

2.2.Context创建过程

public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {//TODO ......ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);// The network security config needs to be aware of multiple// applications in the same process to handle discrepanciesNetworkSecurityConfigProvider.handleNewApplication(appContext);app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);appContext.setOuterContext(app);} catch (Exception e) {if (!mActivityThread.mInstrumentation.onException(app, e)) {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);throw new RuntimeException("Unable to instantiate application " + appClass+ " package " + mPackageName + ": " + e.toString(), e);}}//TODO ......return app;}

LoadedApk.java

在LoadedApk的函数makeApplication中,下面这段语句通过调用了ContextImpl.createAppContext 生成了ContextImpl对象

ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);

在ContextImpl类中,createAppContext函数,调用了另外一个带3个参数的重写函数createAppContext,

可以看出在这个函数里面,通过ContextImpl context = new ContextImpl 这个语句 创建了ContextImpl类的对象,

然后通过函数返回,返回了这个ContextImpl类的对象.

@UnsupportedAppUsagestatic ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {return createAppContext(mainThread, packageInfo, null);}static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,String opPackageName) {if (packageInfo == null) throw new IllegalArgumentException("packageInfo");ContextImpl context = new ContextImpl(null, mainThread, packageInfo,ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName);context.setResources(packageInfo.getResources());context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI: CONTEXT_TYPE_NON_UI;return context;}

上面的步骤创建了appContext,然后通过下面的函数调用把对象appContext传递下去

app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);

在Instrumentation源代码中,newApplication 函数中,Application的attach函数,通过此函数, 把context传递下去

    public Application newApplication(ClassLoader cl, String className, Context context)throws InstantiationException, IllegalAccessException, ClassNotFoundException {Application app = getFactory(context.getPackageName()).instantiateApplication(cl, className);app.attach(context);return app;}

Instrumentation.java

Application类的attach函数,在这个函数中,会把传递进来的context 传递给attachBaseContext函数, attachBaseContext 函数是父类ContextWrapper的函数

同时验证了上面的结论(2.1.ContextWrapper可以关联的可能入口)

public class Application extends ContextWrapper implements ComponentCallbacks2 {
    @UnsupportedAppUsage/* package */ final void attach(Context context) {attachBaseContext(context);mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;}

Application.java

在ContextWrapper的源代码中,可以看到context会在attachBaseContext中赋值给名字为mBase的Context对象的属性

public class ContextWrapper extends Context {@UnsupportedAppUsageContext mBase;public ContextWrapper(Context base) {mBase = base;}/*** Set the base context for this ContextWrapper.  All calls will then be* delegated to the base context.  Throws* IllegalStateException if a base context has already been set.** @param base The new base context for this wrapper.*/protected void attachBaseContext(Context base) {if (mBase != null) {throw new IllegalStateException("Base context already set");}mBase = base;}

ContextWrapper.java

到此处为止,ContextImpl 跟ContextWrapper 的关联已经完成

引用:
Android 开发者,你真的懂Context吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/70.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习概括

文章目录 一、机器学习是什么&#xff1f;二、模型训练YouTube流量预测1. 先写一个具有未知参数的函数&#xff08;Function&#xff09;2. 定义损失&#xff08;从训练数据进行计算&#xff09;3.最优化4.结果分析 Back to framework1.带有未知数的函数&#xff1a;2.定义损失…

K8S应用流程安全(镜像安全 配置管理 访问安全)

应用流程安全 1 应用流程安全1.1 镜像安全1.1.1 构建原则1.1.2 Dockerfile实践1.1.3 构建进阶1.1.4 镜像检测1.1.5 仓库升级1.1.6 高可用仓库1.1.7 镜像策略 1.2 配置管理1.2.1 配置基础1.2.2 YAML安全1.2.3 kustomize1.2.4 基础实践1.2.5 功能复用1.2.6 配置定制1.2.7 补丁实践…

当你按下键盘A键

CPU 里面的内存接口&#xff0c;直接和系统总线通信&#xff0c;然后系统总线再接入一个 I/O 桥接器&#xff0c;这个 I/O 桥接器&#xff0c;另一边接入了内存总线&#xff0c;使得 CPU 和内存通信。再另一边&#xff0c;又接入了一个 I/O 总线&#xff0c;用来连接 I/O 设备&…

el-table 动态合并不定项多级表头

我们的需求是根据不同的厂配不同的多级表头,每个表头有需要合并的项,并且不确定 如图所示 对表格进行循环操作,此处不赘述,最下方有全部代码 表头是单独写在js方便后期更改,然后引入js文件,然后根据情况去调取 // 获取表头getHeader(nv) {this.factoryCodes nv;this.heade…

【UE4 C++】根据指定路径生成静态网格体

在上一篇博客中&#xff08;【UE C】蓝图调用C函数&#xff09;&#xff0c;我们用C创建了一个蓝图函数库&#xff0c;本篇文章在这个蓝图函数库基础上增加一个方法&#xff0c;该方法只需输入一个文件目录路径&#xff0c;就可在场景中生成该目录下得所有静态网格体。&#xf…

第6集丨JavaScript 使用原型(prototype)实现继承——最佳实战3

目录 一、原型继承与属性拷贝1.1 功能说明1.2 功能测试 二、多重继承2.1 功能实现2.2 功能测试 三、寄生式继承四、构造器借用4.1 简单实现4.2 进化版4.2.1 功能实现4.2.2 案例测试 五、借用构造器和原型复制六 综合案例6.1 需求说明6.2 代码实现 一、原型继承与属性拷贝 1.1 功…

css之:is()、:where()和:has()伪元素的运用、使用、important

文章目录 简介1、:is()2、:where()3、:has() 简介 :is()、:where()和:has()伪元素是CSS中用于样式化元素的非常强大的工具。它们是在CSS选择器Level4规范中引入的。它们允许我们将样式应用于符合特定条件的任何元素&#xff0c;例如元素的类型、元素的位置和元素的后代。 1、:i…

【高并发】高并发架构实战:从需求分析到系统设计

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 很多软件工程师的职业规划是成为架构师&#xff0c;但是要成为架构师很多时候要求先有架构设计经验&#xff0c;而不做架构师又怎么会有架构设计经验呢&#xff1f;那么要如何获得架构设…

前端渲染模式CSR,SSR,SSG,ISR,DPR

目录 一、客户端渲染——CSR&#xff08;Client Side Rendering&#xff09; 二、服务器端渲染——SSR&#xff08;Server Side Rendering&#xff09; 三、静态站点生成——SSG&#xff08;Static Site Generation&#xff09; 四、增量静态生成——ISR&#xff08;Increm…

【软件测试】在Windows环境安装Docker(详细步骤)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 下载和安装 1、地…

智慧园区4G+蓝牙+GPS/北斗RTK人员定位系统解决方案

智慧园区是指利用现代科技手段进行精细化管理的园区&#xff0c;人员定位技术被广泛应用在智慧园区。智慧园区人员定位技术通过使用传感器设备&#xff0c;能够实时监测园区内人员的位置和活动情况&#xff0c;从而提高园区的人员管理效率和安全性。 通过人员定位&#xff0c;…

云HIS是什么?HIS系统为什么要上云?云HIS有哪些优点?

一、当前医疗行业HIS的现状与发展趋势 1.医院信息系统&#xff08;HIS&#xff09;经历了从手工到单机再到局域网的两个阶段&#xff0c;随着云计算、大数据新技术迅猛发展&#xff0c;基于云计算的医院信息系统将逐步取代传统局域网HIS , 以适应人们对医疗卫生服务越来越高的要…

常用分类损失CE Loss、Focal Loss及GHMC Loss理解与总结

一、CE Loss 定义 交叉熵损失&#xff08;Cross-Entropy Loss&#xff0c;CE Loss&#xff09;能够衡量同一个随机变量中的两个不同概率分布的差异程度&#xff0c;当两个概率分布越接近时&#xff0c;交叉熵损失越小&#xff0c;表示模型预测结果越准确。 公式 二分类 二…

深入理解预训练(pre-learning)、微调(fine-tuning)、迁移学习(transfer learning)三者的联系与区别

1. 什么是预训练和微调 你需要搭建一个网络模型来完成一个特定的图像分类的任务。首先&#xff0c;你需要随机初始化参数&#xff0c;然后开始训练网络&#xff0c;不断调整参数&#xff0c;直到网络的损失越来越小。在训练的过程中&#xff0c;一开始初始化的参数会不断变化。…

小程序:页面跳转闪屏

自己的笔记&#xff0c;随手记录。扛精走开。 1、问题描述 进入页面&#xff0c;是一个组件&#xff0c;通过路由传参判断是由哪个页面进入&#xff0c;不同的页面拿的已选值不一样&#xff0c;需要回显值&#xff0c;在编辑数据。此时会出现一个问题&#xff0c;A页面中进来…

Serverless和EDA是绝配,亚马逊云科技CTO Werner表示需要用开放心态来重新审视架构

前一段有个很火的博客&#xff0c;讲的是一家全球流媒体企业的监测系统从Serverless微服务改成了单体&#xff0c;成本居然降低了90%&#xff01;这一下子可在网上炸锅了&#xff0c;特别是一些看不惯微服务的、单体应用的拥趸&#xff0c;更是坐不住了。但这并不像吃瓜群众看到…

【ECharts系列】ECharts 图表渲染问题解决方案

1 问题描述 echats 渲染&#xff0c;第一次的时候只出现Y轴数值&#xff0c;不出现X轴数值&#xff0c;切换下页面&#xff0c;X轴数值就能出现。 2 原因分析 如果在使用ECharts渲染时&#xff0c;X轴数值只在切换页面后才出现&#xff0c;可能是因为ECharts在初始化时没有正确…

光速吟唱,Clibor ,批量多次复制依次粘贴工具 快捷输入软件教程

批量多次复制依次粘贴工具 批量复制粘贴工具0.81.exe https://www.aliyundrive.com/s/3sbBaGmHkb8 点击链接保存&#xff0c;或者复制本段内容&#xff0c;打开「阿里云盘」APP &#xff0c;无需下载极速在线查看&#xff0c;视频原画倍速播放。 青县solidworks钣金设计培训 …

Redis进阶 - Redis哨兵

原文首更地址&#xff0c;阅读效果更佳&#xff01; Redis进阶 - Redis哨兵 | CoderMast编程桅杆https://www.codermast.com/database/redis/redis-advance-sentinel.html 思考 slave 节点宕机恢复以后可以找 master 节点同步数据&#xff0c;那么 master 节点宕机怎么办&am…

[Docker] Docker镜像管理和操作实践(二) 文末送书

前言&#xff1a; Docker镜像是容器化应用程序的打包和分发单元&#xff0c;包含了应用程序及其所有依赖项&#xff0c;实现了应用程序的可移植性和一致性。 文章目录 使用Dockerfile创建自定义镜像实践练手1. 创建基于ubuntu的自定义镜像&#xff0c;并安装nginx2. 配置Redis容…