继承结构类图:

ContextWrapper是上下文的包装类,ContextImpl是上下文的实现类,Activity是ContextThemeWrapper的直接子类。
getApplicationContext都做了什么
翻看ContextWrapper源码:
public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
/**
* Set the base context for this ContextWrapper. All calls will then be
* delegated to the base context. Throws
* IllegalStateException if a base context has already been set.
*
* @param base The new base context for this wrapper.
*/
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
@Override
public Context getApplicationContext() {
return mBase.getApplicationContext();
}
....
}ContextWrapper的getApplicationContext方法直接调用mBase的getApplicationContext方法,mBase实际上是ContextImpl类实例,通过上面源码看到,在ContextWrapper类的attachBaseContext方法为其赋值。
什么时候调用的Application的attachBaseContext方法?
在ContextWrapper子类Application类的attach方法中:
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}而Application的attach方法是在Instrumentation类的newApplication方法中调用.
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}继续向上追溯,Instrumentation的newApplication方法是在LoadApk的makeApplication方法中调用:
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
final java.lang.ClassLoader cl = getClassLoader();
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
...
return app;
}最终调用LoadApk的makeApplication方法的地方都在ActivityThread的多个方法中:performLaunchActivity,handleReceiver,handleCreateService,handleBindApplication,attach.
Related Link
本文为Adamin90原创文章,转载无需和我联系,但请注明来自http://www.lixiaopeng.top
