Android Context在四大组件及Application中的表现

文章目录

  • Android Context在四大组件及Application中的表现
    • Context是什么
    • Context源码
    • Activity流程分析
    • Service流程分析
    • BroadcastReceiver流程分析
    • ContentProvider流程分析
    • Application流程分析

Android Context在四大组件及Application中的表现

Context是什么

Context可以理解为“上下文”或”环境“,它提供了访问系统服务及系统资源的功能,Context 参与加载资源、启动Activity、启动Service、获取系统服务/应用资源、创建View、数据库等操作。

在这里插入图片描述

Context有两个实现子类:ContextImpl类和ContextWrapper类。

ContextWrapper类,如其名所言,是一个包装类,内部必须包含一个真正的Context引用(mBase),调用ContextWrapper的方法都会被指向真正的Context对。

ContextThemeWrapper类,如起名所言,内部包含了与Theme(主题)相关的信息,这里的Theme就是定义在Androidmanifest.xml中主题,只有Activity才能定义主题,Servier是不需要主题的,所以Service直接继承自ContextWrapper,Application也同理。

ContextImpl类是真正实现了Context中的所有方法,应用程序中所调用的各种Context类方法都来自该类。

Context源码

public abstract class Context {// 作用1:获取应用相关信息public abstract ApplicationInfo getApplicationInfo();public abstract String getPackageName();public abstract Looper getMainLooper();public abstract int checkPermission(@NonNull String permission, int pid, int uid);// 作用2:获取系统/应用资源// 如 AssetManager、PackageManager、Resources、System Service 以及 color、string、drawable 等public abstract AssetManager getAssets();public abstract Resources getResources();public abstract PackageManager getPackageManager();public abstract Context getApplicationContext();public abstract ClassLoader getClassLoader();public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) { ... }public final String getString(@StringRes int resId) { ... }public final int getColor(@ColorRes int id) { ... }public final Drawable getDrawable(@DrawableRes int id) { ... }public abstract Resources.Theme getTheme();public abstract void setTheme(@StyleRes int resid);public final TypedArray obtainStyledAttributes(@StyleableRes int[] attrs) { ... }// 作用3:四大组件之间的交互// 如启动 Activity、Broadcast、Service,获取 ContentResolver 等public abstract void startActivity(@RequiresPermission Intent intent);public abstract void sendBroadcast(@RequiresPermission Intent intent);public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,IntentFilter filter);public abstract void unregisterReceiver(BroadcastReceiver receiver);public abstract ComponentName startService(Intent service);public abstract boolean stopService(Intent service);public abstract boolean bindService(@RequiresPermission Intent service,@NonNull ServiceConnection conn, @BindServiceFlags int flags);public abstract void unbindService(@NonNull ServiceConnection conn);public abstract ContentResolver getContentResolver();// 作用4:文件相关// 如:获取缓存文件夹、删除文件、SharedPreference 相关等public abstract File getSharedPreferencesPath(String name);public abstract File getDataDir();public abstract boolean deleteFile(String name);public abstract File getExternalFilesDir(@Nullable String type);public abstract File getCacheDir();...public abstract SharedPreferences getSharedPreferences(String name, @PreferencesMode int mode);public abstract boolean deleteSharedPreferences(String name);// 作用5:数据库// 如打开数据库、删除数据库、获取数据库路径等public abstract SQLiteDatabase openOrCreateDatabase(...);public abstract boolean deleteDatabase(String name);public abstract File getDatabasePath(String name);...
}

Activity流程分析

核心源码分析:

// ActivityThread类:private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {// 创建ContextImplContextImpl appContext = createBaseContextForActivity(r);Activity activity = null;try {java.lang.ClassLoader cl = appContext.getClassLoader();// 通过反射创建Activityactivity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);       } try {// 获得ApplicationApplication app = r.packageInfo.makeApplication(false, mInstrumentation);if (activity != null) {appContext.setOuterContext(activity);// 通过attach()方法将appContext和app传递给Activityactivity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window, r.configCallback,r.assistToken, r.shareableActivityToken);}return activity;
}
// Activity类:public class Activity extends ContextThemeWrapper {private Application mApplication;final void attach(Context context, ActivityThread aThread,Instrumentation instr, IBinder token, int ident,Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config, String referrer, IVoiceInteractor voiceInteractor,Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,IBinder shareableActivityToken) {// 最终传递给mBase变量attachBaseContext(context);mApplication = application;        }@Overrideprotected void attachBaseContext(Context newBase) {super.attachBaseContext(newBase);}public final Application getApplication() {return mApplication;}
}

说明:

ContextWrapper 内部包含一个 ContextImpl 类型的成员变量 mBase,mBase的创建是通过 ActivityThread#performLaunchActivity() 创建的。

performLaunchActivity() 主要是四步:

  • 通过 createBaseContextForActivity() 方法创建 ContextImpl 实例,得到appContext。
  • 通过反射创建Activity实例。
  • 获得Application实例,也就是app。
  • 通过 attach() 方法将 appContext 和 app 传递给Activity,初始化 mBase 变量。

Service流程分析

核心源码分析:

// ActivityThread类; private void handleCreateService(CreateServiceData data) {       Service service = null;try {// 获取ApplicationApplication app = packageInfo.makeApplication(false, mInstrumentation);// 通过反射创建Serviceservice = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);// 创建ContextImplContextImpl context = ContextImpl.getImpl(service// 将context和app传递给Serviceservice.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());} 
}

说明:

Service 的流程和 Activity 基本一致。

BroadcastReceiver流程分析

核心源码分析:

// ActivityThread类:private void handleReceiver(ReceiverData data) {Application app;BroadcastReceiver receiver;ContextImpl context;try {// 获取Applicationapp = packageInfo.makeApplication(false, mInstrumentation);// 获取ContextImplcontext = (ContextImpl) app.getBaseContext();// 通过反射创建BroadcastReiverreceiver = packageInfo.getAppFactory().instantiateReceiver(cl, data.info.name, data.intent);} try {// 实际传递的是ReceiverRestrictedContextreceiver.onReceive(context.getReceiverRestrictedContext(),data.intent);} 
}
// ReceiverRestrictedContext类:@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,String broadcastPermission, Handler scheduler) {if (receiver == null) {return super.registerReceiver(null, filter, broadcastPermission, scheduler);} else {throw new ReceiverCallNotAllowedException("BroadcastReceiver components are not allowed to register to receive intents");}
}@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {throw new ReceiverCallNotAllowedException("BroadcastReceiver components are not allowed to bind to services");
}

说明:

BroadcastReceiver 不是 Context 的子类,它的 Context 对象是从其他地方传递来的。

ReceiverRestrictedContext 是 ContextWrapper 的子类, 重载了 registerReceiver 和 bindService 方法,因此广播的注册依赖与 Context。

ContentProvider流程分析

核心源码分析:

// ActivityThread类:private ContentProviderHolder installProvider(Context context,ContentProviderHolder holder, ProviderInfo info,boolean noisy, boolean noReleaseNeeded, boolean stable) {ContentProvider localProvider = null;IContentProvider provider;if (holder == null || holder.provider == null) {        Context c = null;ApplicationInfo ai = info.applicationInfo;// 获得ContextImplc = context.createPackageContext(ai.packageName,                                      									 Context.CONTEXT_INCLUDE_CODE);             try {// 通过反射创建ContentProviderlocalProvider = packageInfo.getAppFactory().instantiateProvider(cl, info.name);// 传入ContextlocalProvider.attachInfo(c, info);} } return retHolder;
}
// ContentProvide类:private Context mContext = null;public void attachInfo(Context context, ProviderInfo info) {attachInfo(context, info, false);
}private void attachInfo(Context context, ProviderInfo info, boolean testing) {if (mContext == null) {mContext = context;        ContentProvider.this.onCreate();}
}

说明:

ContentProvider 不是 Context 的子类,在应用启动时会自动创建 ContentProvider 并传入 Context 对象。

Application流程分析

核心源码分析:

// ActivityThread类:private Application mApplication;public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {if (mApplication != null) {return mApplication;}Application app = null;try {// 创建ContextImpl实例ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);// 通过反射创建Application,并调用attach()方法传入Contextapp = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);} mActivityThread.mAllApplications.add(app);// 赋值mApplication = app;if (instrumentation != null) {try {// 回调Application#onCreate()方法instrumentation.callApplicationOnCreate(app);} }return app;
}

说明:

makeApplication() 方法主要分四步:

  • 通过 createAppContext() 方法创建 ContextImpl 实例,也就是 appContext。
  • 通过 newApplication() 方法反射创建 Application 实例,接着调用 Application#attach() 方法传入 Context,初始化 mBase 变量。
  • 将 Application 保存为全局变量。
  • 回调 Application#onCreate() 方法。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

深入ArkUI:深入实战组件text和text input

文章目录 Text组件介绍Text组件的属性方法Text:文本显示组件4.3TextInput组件实战案例:图片宽度控制页面本文总结要点回顾在今天的课程中,我们将深入学习ArkUI提供的基础组件,着重探讨text和text input两个组件。 Text组件介绍 Text组件是一个用于显示文本的组件,其主要作…

跟着LearnOpenGL学习11--材质

文章目录 一、材质二、设置材质三、光的属性四、不同的光源颜色 一、材质 在现实世界里&#xff0c;每个物体会对光产生不同的反应。 比如&#xff0c;钢制物体看起来通常会比陶土花瓶更闪闪发光&#xff0c;一个木头箱子也不会与一个钢制箱子反射同样程度的光。 有些物体反…

CEC2017(Python):五种算法(SSA、RFO、OOA、PSO、GWO)求解CEC2017

一、5种算法简介 1、麻雀搜索算法SSA 2、红狐优化算法RFO 3、鱼鹰优化算法OOA 4、粒子群优化算法PSO 5、灰狼优化算法GWO 二、CEC2017简介 参考文献&#xff1a; [1]Awad, N. H., Ali, M. Z., Liang, J. J., Qu, B. Y., & Suganthan, P. N. (2016). “Problem defin…

WEB通讯技术。前端实现SSE长连接,nodejs+express搭建简单服务器,进行接口调试,通过curl请求数据

描述 长连接&#xff08;Keep-Alive&#xff09;是一种HTTP/1.1的持久连接技术&#xff0c;它允许客户端和服务器在一次TCP连接上进行多个HTTP请求和响应&#xff0c;而不必为每个请求/响应建立和断开一个新的连接。长连接有助于减少服务器的负载和提高性能。 长连接的HTTP请…

SpringBoot2.7.12整合Knife4j

SpringBoot2.7.12整合Knife4j 是什么 Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案 添加依赖 <!--引入Knife4j的官方start包,该指南选择Spring Boot版本<3.0,开发者需要注意--> <dependency><groupId>com.github.xiaoymin</groupId>&l…

【Angular 】Angular 模板中基于角色的访问控制

您是否在Angular模板中实现角色库访问控制&#xff1f;一种方法是通过*ngIf&#xff0c;但我不会选择该路径&#xff0c;因为它将在Angular模板中包含自定义函数&#xff0c;并且很难维护。正确的方法是使用Angular结构指令&#x1f680;. 什么是RBAC&#xff1f; 基于角色的…

基于 eBPF 构建下一代智能可观测系统

作者&#xff1a;梵登、千陆 本文基于 KubeCon China 2023 分享整理 我们今天分享的主题是基于 eBPF 构建下一代智能可观测系统。 在开始之前呢&#xff0c;我先介绍一下我们自己。我是刘恺&#xff0c;花名是千陆&#xff0c;目前是阿里云 ARMS K8s 监控子产品的负责人。这…

自然语言处理(第16课 机器翻译4、5/5)

一、学习目标 1.学习各种粒度的系统融合方法 2.学习两类译文评估标准 3.学习语音翻译和文本翻译的不同 4.学习语音翻译实现方法 二、系统融合 以一个最简单的例子来说明系统融合&#xff0c;就是相当于用多个翻译引擎得到不同的翻译结果&#xff0c;然后选择其中最好的作为…

GBASE南大通用-小内存单机安装GBase 8c分布式数据库实践

* 这种小内存部署方式仅用于分布式数据库个人学习使用&#xff0c;不建议用于其他用途。 随着数据高并发复杂场景业务需求不断增多&#xff0c;信息数据呈现出爆炸式增长、多源多维、数据类型繁复等特征。在这一趋势下&#xff0c;目前分布式数据库因其架构的天然优势&#xf…

【MySQL】数据库之小题练习(完全备份和增量备份的数据恢复,以及断点恢复)

目录 先创建库&#xff0c;创建表&#xff0c;完成三次数据的录入以及第一次的完全备份&#xff0c;第二次和第三次的增量备份&#xff1b; 第一次完全备份操作 第二次插入后做增量备份操作 第三次 插入后做增量备份操作 1、完全备份恢复&#xff0c;获取一班的人的成绩 …

SAP问题 OPEN SQL 取不到值

关键&#xff1a;数据库中有数据&#xff0c;但是open sql取不到数据 背景&#xff1a; 标准程序在测试环境正常执行&#xff0c;在生产环境报错。 解决过程&#xff1a; 第一步&#xff1a;分析执行结果不一致可能的原因&#xff1a; 1.测试数据问题&#xff0c;可能性小&…

甄知猪齿鱼2.6版本来了,自动化助手帮你轻松提升生产力!

年末之际&#xff0c;我们带来了猪齿鱼V2.6.0的新版本大礼包&#xff01;在这次更新中&#xff0c;我们进行了自动化功能的升级和优化&#xff0c;助您轻松提升生产力&#xff0c;更好地应对各种项目管理挑战。 自动化助手 自动化助手是由触发器、条件、动作3个元素组成&#x…

打开3d模型时显示不匹配怎么办---模大狮模型网

当3d模型打开时&#xff0c;显示不匹配的情况可能有以下几个原因和解决方法&#xff1a; 文件格式不匹配&#xff1a;检查您所使用的3D软件是否支持打开该模型文件格式。不同的软件支持不同的文件格式&#xff0c;如果文件格式不匹配&#xff0c;可能无法正确加载和显示模型。尝…

反射讲解(有图有真相)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、反射是什么&#xff1f;二、反射有啥好处&#xff1f;1. 没反射2. 有反射 三、反射的常用方法1. 获取 Class 对象&#xff1a;2. 获取类的构造方法&#xf…

5214手持式千兆网络质量测试仪

5214手持式千兆网络质量测试仪 简述&#xff1a; 5214 手持式千兆网络质量测试仪是中电科思仪科技股份有限公司研发的综合性网络测 试仪器。此仪器具有网络故障的排查&#xff0c;网络设备的现场维护&#xff0c;网络性能的测试和分析&#xff0c;协议 仿真、解码、统计等功能…

目标检测 YOLOv5 - 推理时的数据增强

目标检测 YOLOv5 - 推理时的数据增强 flyfish 版本 YOLOv5 6.2 参考地址 https://github.com/ultralytics/yolov5/issues/303在训练时可以使用数据增强&#xff0c;在推理阶段也可以使用数据增强 在测试使用数据增强有个名字叫做Test-Time Augmentation (TTA) 实际使用中使…

Arduino驱动VL6180X光学测距传感器(OLED显示)

Arduino驱动VL6180X光学测距传感器&#xff08;OLED显示&#xff09; 简介原理模块参数接线图代码结果 简介 VL6108X三合一光电模块&#xff0c;芯片内集成了IR VSEL(vertical-cavity surface-emitting laser)红外垂直腔面发射激光器光源、接近传感器、环境光传感器&#xff0…

Java创建线程执行任务的方法(一)

目录 1.继承Thread类 2.实现Runnab类 2.1实现Runnable类 2.2使用Lambda表达式 3.实现Callable类 3.1返回Integer类型数据 3.2返回String类型数据 3.3返回Object类型数据 4.匿名内部类 创建线程的方法&#xff1a;继承Thread类&#xff1b;实现Runnab类&#xff1b;匿名…

Apipost一键压测参数化功能详解

最近更新中Apipost对UI页面进行了一些调整&#xff0c;另外一键压测功能支持参数化&#xff01;本篇文章将详细介绍这些改动&#xff01; API调试页面的细节改动 在请求区填入请求参数或脚本时会有相应的标识 如在Query中填入多个参数时上方会展示数量 在预、后执行脚本中写…

基于Java车间工时管理系统(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…