深入解析Android App开发中Context的用法

2019-12-10 18:57:33于丽

由于includeCode传入的是true,所以首先从mPackages中获取,如果没有,则new一个出来,并放入mPackages里面去,注意,这里的mPackages是ActivityThread中的属性。
下面继续分析一下LoadedApk这个类中的makeApplication函数

try { 
      java.lang.ClassLoader cl = getClassLoader(); 
      //创建一个ContextImpl对象 
      ContextImpl appContext = new ContextImpl(); 
      appContext.init(this, null, mActivityThread); 
      app = mActivityThread.mInstrumentation.newApplication( 
          cl, appClass, appContext); 
      appContext.setOuterContext(app); 
    } catch (Exception e) { 
      if (!mActivityThread.mInstrumentation.onException(app, e)) { 
        throw new RuntimeException( 
          "Unable to instantiate application " + appClass 
          + ": " + e.toString(), e); 
      } 
    } 

这里创建了一个ContextImpl对象,并调用了它的init方法,现在进入init方法。  

mPackageInfo = packageInfo; 
mResources = mPackageInfo.getResources(mainThread); 

对mPackageInof和mResources两个变量初始化
回到makeApplication中,创建了一个Application对象,并将appContext传进去,其实就是将appContext传递给ContextWrapper中的Context类型变量(Application也是继承ContextWrapper)
2、Activity中的Context
在创建一个Activity时,经过辗转调用,会执行handleLaunchActivity(),然后调用performLaunchActivity(),该方法创建ContextImpl代码如下:

r.packageInfo= getPackageInfo(aInfo.applicationInfo,
          Context.CONTEXT_INCLUDE_CODE);
 
ContextImplappContext = new ContextImpl();
        appContext.init(r.packageInfo,r.token, this);
        appContext.setOuterContext(activity);
 
activity.attach(appContext,this, getInstrumentation(), r.token,
            r.ident, app, r.intent,r.activityInfo, title, r.parent,
            r.embeddedID,r.lastNonConfigurationInstance,
            r.lastNonConfigurationChildInstances, config);