`
zzu_007
  • 浏览: 23889 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Acitivy创建Context的过程(一)

阅读更多
page1
从本篇文章开始,我们分析一下Activity创建Context的过程.
Context是在ActivityThread的performLaunchActivity函数中创建的, 因此我们就从performLaunchActivity函数作为入口开始分析:
1     private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2         // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
3
4         ActivityInfo aInfo = r.activityInfo;
5         if (r.packageInfo == null) {
6             r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
7                     Context.CONTEXT_INCLUDE_CODE);
8         }
9
10         ComponentName component = r.intent.getComponent();
11         if (component == null) {
12             component = r.intent.resolveActivity(
13                 mInitialApplication.getPackageManager());
14             r.intent.setComponent(component);
15         }
16
17         if (r.activityInfo.targetActivity != null) {
18             component = new ComponentName(r.activityInfo.packageName,
19                     r.activityInfo.targetActivity);
20         }
21
22         Activity activity = null;
23         try {
24             java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
25             activity = mInstrumentation.newActivity(
26                     cl, component.getClassName(), r.intent);
27             StrictMode.incrementExpectedActivityCount(activity.getClass());
28             r.intent.setExtrasClassLoader(cl);
29             if (r.state != null) {
30                 r.state.setClassLoader(cl);
31             }
32         } catch (Exception e) {
33             if (!mInstrumentation.onException(activity, e)) {
34                 throw new RuntimeException(
35                     "Unable to instantiate activity " + component
36                     + ": " + e.toString(), e);
37             }
38         }
39
40         try {
41             Application app = r.packageInfo.makeApplication(false, mInstrumentation);
42
43             if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
44             if (localLOGV) Slog.v(
45                     TAG, r + ": app=" + app
46                     + ", appName=" + app.getPackageName()
47                     + ", pkg=" + r.packageInfo.getPackageName()
48                     + ", comp=" + r.intent.getComponent().toShortString()
49                     + ", dir=" + r.packageInfo.getAppDir());
50
51             if (activity != null) {
52                 Context appContext = createBaseContextForActivity(r, activity);
53                 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
54                 Configuration config = new Configuration(mCompatConfiguration);
55                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
56                         + r.activityInfo.name + " with config " + config);
57                 activity.attach(appContext, this, getInstrumentation(), r.token,
58                         r.ident, app, r.intent, r.activityInfo, title, r.parent,
59                         r.embeddedID, r.lastNonConfigurationInstances, config);
60
61                 if (customIntent != null) {
62                     activity.mIntent = customIntent;
63                 }
64                 r.lastNonConfigurationInstances = null;
65                 activity.mStartedActivity = false;
66                 int theme = r.activityInfo.getThemeResource();
67                 if (theme != 0) {
68                     activity.setTheme(theme);
69                 }
70
71                 activity.mCalled = false;
72                 mInstrumentation.callActivityOnCreate(activity, r.state);
73                 if (!activity.mCalled) {
74                     throw new SuperNotCalledException(
75                         "Activity " + r.intent.getComponent().toShortString() +
76                         " did not call through to super.onCreate()");
77                 }
78                 r.activity = activity;
79                 r.stopped = true;
80                 if (!r.activity.mFinished) {
81                     activity.performStart();
82                     r.stopped = false;
83                 }
84                 if (!r.activity.mFinished) {
85                     if (r.state != null) {
86                         mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
87                     }
88                 }
89                 if (!r.activity.mFinished) {
90                     activity.mCalled = false;
91                     mInstrumentation.callActivityOnPostCreate(activity, r.state);
92                     if (!activity.mCalled) {
93                         throw new SuperNotCalledException(
94                             "Activity " + r.intent.getComponent().toShortString() +
95                             " did not call through to super.onPostCreate()");
96                     }
97                 }
98             }
99             r.paused = true;
100
101             mActivities.put(r.token, r);
102
103         } catch (SuperNotCalledException e) {
104             throw e;
105
106         } catch (Exception e) {
107             if (!mInstrumentation.onException(activity, e)) {
108                 throw new RuntimeException(
109                     "Unable to start activity " + component
110                     + ": " + e.toString(), e);
111             }
112         }
113
114         return activity;
115     }
第52行(ActivityThread->performLaunchActivity)调用createBaseContextForActivity函数为刚刚创建的activity对象创建Context对象, 关于performLaunchActivity函数的详细分析可以参考page2文件.
第57-59行(ActivityThread->performLaunchActivity)调用Activity的attach函数, 关于attach函数的详细分析可以参考page5文件.
page2
ActivityThread的createBaseContextForActivity函数定义如下:
1     private Context createBaseContextForActivity(ActivityClientRecord r,
2             final Activity activity) {
3         ContextImpl appContext = new ContextImpl();
4         appContext.init(r.packageInfo, r.token, this);
5         appContext.setOuterContext(activity);
6
7         // For debugging purposes, if the activity's package name contains the value of
8         // the "debug.use-second-display" system property as a substring, then show
9         // its content on a secondary display if there is one.
10         Context baseContext = appContext;
11         String pkgName = SystemProperties.get("debug.second-display.pkg");
12         if (pkgName != null && !pkgName.isEmpty()
13                 && r.packageInfo.mPackageName.contains(pkgName)) {
14             DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
15             for (int displayId : dm.getDisplayIds()) {
16                 if (displayId != Display.DEFAULT_DISPLAY) {
17                     Display display = dm.getRealDisplay(displayId);
18                     baseContext = appContext.createDisplayContext(display);
19                     break;
20                 }
21             }
22         }
23         return baseContext;
24     }
第3行(ActivityThread->createBaseContextForActivity)会new一个ContextImpl对象. ContextImpl的构造函数的详细分析可以参考page3文件.
第4行(ActivityThread->createBaseContextForActivity)会调用ContextImpl的init函数, 关于init函数的详细分析可以参考page4文件.
第5行(ActivityThread->createBaseContextForActivity)调用ContextImpl的setOuterContext函数, ContextImpl的setOuterContext函数定义如下:
final void setOuterContext(Context context) {
        mOuterContext = context;
    }
这样, ContextImpl也会拿着activity对象.

第10-22行(ActivityThread->createBaseContextForActivity)是干什么呢?不知道.
page3
在这里我们分析一下ContextImpl类的构造过程.我们先来看一下ContextImpl类的继承体系, ContextImpl类的定义如下:
class ContextImpl extends Context {
public abstract class Context {

ContextImpl类的构造函数如下所示
ContextImpl() {
        mOuterContext = this;
    }
在ContextImpl的构造函数中, 只是初始化了成员变量mOuterContext, 使之指向该ContextImpl对象.
成员变量mOuterContext的定义如下:
private Context mOuterContext;

妈的, 就这么简单.
分享到:
评论

相关推荐

    Android启动APP时黑屏白屏的解决方法

    首先系统的服务会先检查startActivity中的intent的信息,然后在去创建进程,最后才是执行启动Acitivy的操作。而我们上面提到的显示白黑屏的问题,就是在这段时间内产生的。 系统在绘制页面加载布局之前,首先会初始...

    Android Service中使用Toast无法正常显示问题的解决方法

    在做Service简单练习时,在Service中的OnCreate、OnStart、OnDestroy三个方法中都像在Activity中同样的方法调用了Toast.makeText,并在Acitivy中通过两个按钮来调用该服务的onStart和onDestroy方法: DemoService...

    dnSpy-net-win32-222.zip

    dnSpy-net-win32-222.zip

    和美乡村城乡融合发展数字化解决方案.docx

    和美乡村城乡融合发展数字化解决方案.docx

    如何看待“适度宽松”的货币政策.pdf

    如何看待“适度宽松”的货币政策.pdf

    C#连接sap NCO组件 X64版

    NCO 3.0.18 64位

    法码滋.exe法码滋2.exe法码滋3.exe

    法码滋.exe法码滋2.exe法码滋3.exe

    基于MATLAB的导航科学计算库

    * GPS IMU经典15维ESKF松组合 * VRU/AHRS姿态融合算法 * 捷联惯导速度位置姿态解算例子 * UWB IMU紧组合融合 * 每个例子自带数据集

    毕业设计Jupyter Notebook基于深度网络的垃圾识别与分类算法研究项目源代码,用PyTorch框架中的transforms方法对数据进行预处理操作,后经过多次调参实验,对比不同模型分类效果

    在现代社会生活与生产活动下,不可避免的会产生巨量且多样的垃圾。我国的人口和经济总量均位居世界前列,因此,必然面临着庞大数量的垃圾处理的难题。如何通过人工智能来对垃圾进行有效分类,成为当前备受关注的研究热点。本文为展开基于深度网络的垃圾识别与分类算法研究,先使用PyTorch框架中的transforms方法对数据进行预处理操作,后经过多次调参实验,对比朴素贝叶斯模型、Keras卷积神经网络模型、ResNeXt101模型的垃圾分类效果。确定最佳分类模型是ResNeXt101,该模型在GPU环境下的分类准确率达到了94.7%。最后利用postman软件来测试API接口,完成图片的在线预测。在微信开发者工具的基础上,利用一些天行数据的垃圾分类的API接口再结合最佳模型的API接口,开发出了一个垃圾分类微信小程序。本文的研究内容丰富和完善了垃圾图像分类的相关研究,也为后续的研究提供了一定的参考价值。

    C#上位机开发与工控通讯实战课程

    一、上位机简介   在单片机项目开发中,上位机也是一个很重要的部分,主要用于数据显示(波形、温度等)、用户控制(LED,继电器等),下位机(单片机)与 上位机之间要进行数据通信的两种方式都是基于串口的: USB转串口 —— 上位机和下位机通过USB转串口连接线直接相连进行数据交互 串口转WIFI(ESP8266)—— 上位机和下位机基于TCP/IP协议通过以太网或者WIFI传输数据 串口转蓝牙(HC-06)—— 不多用,暂不介绍   Windows上位机(EXE可执行程序),最早用VB语言开发,后来由于C++的发展,采用MFC开发,近几年,微软发布了基于.NET框架的面向对象语言C#,更加稳定安全,再配合微软强大的VS进行开发,效率奇高。   本文使用Visual Studio 2022作为开发环境,上位机开发主要有WPF框架与Winform框架,他们都是基于.NET框架 WPF需要C/S基础,使用XAML来构建应用UI,界面比较美观,但是内存开销大 Winform可以使用窗口控件来构建应用,比较简单易学 二、开发环境设置 1. 安装Visual Studio 首先,确保你已经

    course_s4_ALINX_ZYNQ_MPSoC开发平台Linux驱动教程V1.04.pdf

    course_s4_ALINX_ZYNQ_MPSoC开发平台Linux驱动教程V1.04.pdf

    基于JavaWeb的毕业季旅游一站式定制服务平台_88z1j4jp_208-wx-(1).zip

    基于JavaWeb的毕业季旅游一站式定制服务平台_88z1j4jp_208-wx-(1).zip

    数据恢复软件 Apeaksoft Data Recovery for Mac v1.6.16

    Apeaksoft Data Recovery for Mac v1.6.16

    cms测试练习项目(linux系统部署)

    cms测试练习项目(linux系统部署),可以用来进行python的测试练手项目

    大学录取结果数据集,大学录取结果分析数据,大学录取因素分析

    数据集简介:大学录取结果分析 概述 大学录取结果数据集包含了有关大学录取过程的信息,包括关键变量,可用于分析不同学术因素与申请者是否被录取之间的关系。该数据集非常适合进行探索性数据分析、训练预测模型以及研究影响录取决策的因素。 数据集列描述 admit:指示申请者是否被录取(1=被录取,0=未录取)。 paes:申请者在高等教育能力测试(PAES)中获得的分数。 nem:中学教育成绩平均分,评分范围从1.0到7.0。 rank:申请者在其班级中的排名,数值越低表示排名越好。 数据集目的 本数据集旨在让用户探索学术指标(如PAES分数、GPA和排名)与大学录取成功率之间的关系。这可以用于: 开发预测模型:基于学术表现预测录取可能性。 识别趋势:找出影响录取的关键学术因素。 生成可视化图表:理解分数分布及录取结果的关系。 数据集规模 记录数:1813条。 列数:5列。

    STM32F427+rtthread下的bootload 网口(webclient)+串口(ymodem)传输,代码无质量,谨慎使用

    STM32F427+rtthread下的bootload 网口(webclient)+串口(ymodem)传输,代码无质量,谨慎使用

    电影院购票-JAVA-基于springBoot的电影院购票系统设计与实现(毕业论文)

    1. 用户管理功能 用户注册与登录:用户可以通过手机号、邮箱等方式注册账户,并且可以通过账号登录系统进行购票、查看历史订单等操作。 个人信息管理:用户可以查看和修改个人信息(如姓名、手机号、邮箱等),并进行密码重置等操作。 实名认证:部分电影院购票系统要求用户进行实名认证,确保用户身份的真实性。 2. 电影信息展示功能 电影排片查询:用户可以查看当前和未来一段时间内的电影排片表,包括电影名称、上映时间、影片时长、类型、导演、演员等详细信息。 电影详情页:点击具体电影后,用户可以查看电影的详细信息,如剧情介绍、影评、评分、预告片等内容。 电影评分与评论:用户可以查看其他观众的评分和评论,也可以对已观看的电影进行评分和评论。 3. 座位选择与预定功能 影厅座位图:系统展示每场次的影厅座位图,用户可以通过座位图查看当前座位的状态(如可选、已选、已售出、VIP座位等)。 座位选择:用户可以选择自己喜欢的座位,系统会实时更新座位的可用状态,避免重复选择。 座位偏好设置:用户可以设置自己的座位偏好,如选择前排、中排或后排,靠窗或靠过道等。 4. 电影票购买与支付功能 票价展示:系统会展示每个座位的

    Bukkit-BETA1.8.1服务端核心

    Bukkit-BETA1.8.1服务端核心

    快速排序在Go中的高效实现与应用

    内容概要:本文详细介绍了快速排序算法的原理和在Go语言中的高效实现方法。首先解释了快速排序的基本思想和实现步骤,接着提供了Go语言中实现快速排序的核心代码,并讨论了性能优化策略。最后,通过具体的应用场景实例,展示了快速排序在实际项目中的高效应用。 适合人群:具备一定编程基础,特别是对Go语言感兴趣的开发人员。 使用场景及目标:①理解快速排序算法的基本原理和分治策略;②学习如何在Go语言中高效实现快速排序;③掌握快速排序在实际项目中的应用实例。 阅读建议:本文不仅详细讲解了快速排序的原理,还提供了具体的实现代码和优化策略,建议读者在阅读过程中尝试实现和调试代码,以便更好地理解和掌握相关知识点。

    java毕设项目之学生社团管理系统+vue(完整前后端+说明文档+mysql+lw).zip

    项目包含完整前后端源码和数据库文件,均测试可正常运行 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 部署容器:tomcat7

Global site tag (gtag.js) - Google Analytics