「这是我参与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组件,它已经创建和启动完成了