首先我们来看下Application的继承关系
package android.app;
public class Application extends ContextWrapper implements ComponentCallbacks2 {
}
从这里可以看出Application继承自ContextWrapper,所以当我们在调用Application的getApplicationContext时,实际上调用的是ContextWapper的getApplicationContext
package android.content;
public class ContextWrapper extends Context {
Context mBase;
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
@Override
public Context getApplicationContext() {
return mBase.getApplicationContext();
}
}
那这个mBase.getApplicationContext()获取的是啥?因为mBase是个接口,它的实现类是ContextImpl,所以我们来具体看看mBase.getApplicationContext()的实现
package android.app;
class ContextImpl extends Context {
final @NonNull LoadedApk mPackageInfo;
@Override
public Context getApplicationContext() {
return (mPackageInfo != null) ? mPackageInfo.getApplication() : mMainThread.getApplication();
}
}
看到这里疑问又来了,这完全是俄罗斯套娃啊!mPackageInfo.getApplication()获取的又是啥?
package android.app;
public final class LoadedApk {
private Application mApplication;
Application getApplication() {
return mApplication;
}
}
搜嘎,原来getApplicationContext()获取到的就是Application啊!
休息会儿让我喝口水歇歇......
上面讲到getApplicationContext()获取到的就是Application的,那为啥在attachBaseContext方法中获取getApplicationContext()为空呢?嘿嘿,我也想问......
接下来我们继续来分析看看attachBaseContext是在什么时候调用的
package android.app;
public class Application extends ContextWrapper implements ComponentCallbacks2 {
public LoadedApk mLoadedApk;
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
}
最后根据上面一步步的分析,getApplicationContext()获取到的就是Application对象,而Application对象是通过mPackageInfo.getApplication()获取的,而mPackageInfo(mLoadedApk)是在attachBaseContext之后才被赋值的,所以你在attachBaseContext方法中获取getApplicationContext()当然是null啦!!!
网友评论