Android应用开发之Acitivy创建Context的过程(一)
白羽 2018-08-10 来源 :网络 阅读 1251 评论 0

摘要:本文将带你了解Android应用开发之Acitivy创建Context的过程(一),希望本文对大家学Android有所帮助

        本文将带你了解Android应用开发之Acitivy创建Context的过程(一),希望本文对大家学Android有所帮助


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频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程