在上一篇文章Activity对象的创建后,接着会创建ContextImpl,PhoneWindow,DecorView等对象。在这篇文章来分析ContextImpl对象的产生。
ContextImpl对象的创建是在Activity对象创建之后创建的,而Activity对象的创建在ActivityThread.performLaunchActivity()方法才完成创建的,那么继续进去ActivityThread.performLaunchActivity()看看。
public final class ActivityThread {
private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
.......
Activity activity = null;
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent); //创建Activity
......
if (activity != null) {
ContextImpl appContext = new ContextImpl();//创建ContextImpl
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);//保存Activity 到ContextImpl中
......
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstance,
r.lastNonConfigurationChildInstances, config);
......
}
......
return activity;
}
}
在第7行创建出Activity对象后,如果不为空,接着在11行创建ContextImpl对象,在13行ContextImpl把当前的Acticity保存在ContextImpl类成员变量中以便可以操作Activity组件。
我们平时都是说Context对象,Context对象,为什么会创建ContextImpl对象的?我们去看看Activity的继承关系就一目了然。
由继承图可知:我们平时说的Context对象,其实对象的真正类型是ContextImpl对象。ContextImpl才是真正实现Context。
Activity组件没有Context的成员变量,那么我们平时用的Context是哪里来的?由继承关系图可知:其实Activity组件是引用了父类的mBase成员变量的 ContextImpl对象。—–>a
有了这个对象我们就可以操作相应的操作, Context对象运行上下文有什么作用?
因此Context对象是如此的重要,每个Activity都会关联一个Context对象。由a可知,Activity 组件关联的Context 是引用到父类的mBase成员变量。父类的mBase成员变量是怎么赋值的?在performLaunchActivity函数调用activity.attach(…)函数,进入一探究竟。
public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks2, Window.OnWindowDismissedCallback {
.......
final void attach(Context context,...) {
......
attachBaseContext(context);
.....
}
}
看到这里调用attachBaseContext函数,进去看看
public class ContextThemeWrapper extends ContextWrapper {
@Override
protected void attachBaseContext(Context newBase) {
mBase = newBase;
super.attachBaseContext(newBase);
}
}
其实就是把ContextThemeWrapper mBase成员变量赋值,之后调用super.attachBaseContext(newBase);其实同理得,就是为ContextWrapper 的mBase成员变量赋值。