Context(三) -- Activity创建Context

248 阅读2分钟

「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战

Activity创建Context也需要从performLaunchActivity()分析

  • (1) 先创建一个Activity的ContextImpl
  • (2) 再创建了一个Activity实例
  • (3) 将创建的activity赋值给ContextImpl的mOuterContext, 这样就可以通过ContextImpl调用Activity的方法和变量
  • (4) 调用attach()将appContext传入到Activity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  ...
  //(1)
  ContextImpl appContext = createBaseContextForActivity(r);
  try {
    java.lang.ClassLoader cl = appContext.getClassLoader();
    //(2)
    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
   
  } catch (Exception e) {
    ...
  }
  try {
    if (activity != null) {
      //(3)
      appContext.setOuterContext(activity);
      //(4)
      activity.attach(...);

    }
    ...
  } catch (Exception e) {
    ...        
  }
  return activity;
}

setOuterContext具体做了什么

  • 参数context描述的是一个正在启动的Activity组件,ContextImpl类的成员函数setOuterContext只是简单地将它保存在成员变量mContext中,表明当前正在处理的一个ContextImpl对象是用来描述一个Activity组件的运行上下文环境的
class  ContextImpl  extends  Context {
     ......
     private  Context mOuterContext;
     ......
     final  void  setOuterContext(Context context) {
         mOuterContext = context;
     }
     ......
}

我们看看attach()函数都有什么

  • (1) 调用attachBaseContext(),会根据继承关系一直调用到ContextWrapper, 然后将ContextImpl类型的Context传进去,赋值给mBase
final void attach(...) {
  //(1)
  attachBaseContext(context);
 }

ContextThemeWrapper.attachBaseConext

  • ContextThemeWrapper中attachBaseConext()方法,首先调用父类ContextWrapper的成员函数attachBaseConext将newBase保存到父类ContextWrapper,再将ContextImpl对象保存在ContextThemeWrapper的mBase中
public class ContextThemeWrapper extends ContextWrapper {
    private Context mBase;
    ......
    @Override protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(newBase);
        mBase = newBase;
    }
    ......
}

ContextWrapper.attachBaseConext

  • ContextWrapper类只是一个代理类,它将它的功能交给ContextImpl类来具体实现。这一步执行完成之后,当前正在启动的Activity组件的运行上下文环境就设置完成了
public class ContextWrapper extends Context {
    Context mBase;
    ......
    protected void attachBaseContext(Context base) {
        ...
        mBase = base;
    }
    ......
}

总结:

  • Android应用运行的上下文环境是使用一个ContextImpl来描述的,这个ContextImpl会保存在Activity的父类ContextThemeWrapper和ContextWrapper的成员变量mBase中,即ContextThemeWrapper类和ContextWrapper类的成员变量mBase指向的是一个ContextImpl对象
  • 一个Activity就有一个Context,而且生命周期和Activity类相同
  • 在ActivityThread的performLaunchActivity中,会调用Instrumentation.callActivityOnCreate()来通知当前正在启动的Activity组件,它已经创建和启动完成了