Application 实例化过程
//我们的ActivityThread就是通过这个Handler来通知启动Application的
//并且Activity也是它通知启动的具体可以看ActivityThread中各种handle开头的方法
final H mH = new H();
//看来还是通过Handler
public void handleMessage(Message msg) {
...
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
private void handleBindApplication(AppBindData data) {
...
//创建Application实例对象
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
}
makeApplication是LoadedApk类中的方法
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
Application app = null;
try {
java.lang.ClassLoader cl = getClassLoader();
...
//注意这里,这里创建了我们伟大的Context实例
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
}
}
可以看到我们的Application的实例对象是在Instrumentation中通过反射创建的
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
Resource 实例化过程
通过上面Application的实例化对象过程分析我们看到了Context的实例化对象即ContextImpl ,这个很重要。
我们知道我们在Activity中通过调用getResource()方法获取Resource对象
@Override
public Resources getResources() {
// 可以看到最终调用的是mBase(Context实例)的方法
return mBase.getResources();
}
public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
...
}
那么mBase的实例对象是什么时候创建的呢?
//Instrumentation 类
//创建Application实例的时候调用的这个方法
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
/**
* @hide
*/
/* package */ final void attach(Context context) {
//可以看到
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
//也就是说mBase实际上就是ContextImpl
mBase = base;
}
所以在ContextImpl中看mResouce什么时候被创建的
void setResources(Resources r) {
if (r instanceof CompatResources) {
((CompatResources) r).setContext(this);
}
mResources = r;
}
到此为止,可以看看这个方法什么时候被调用的,但是最后都会发现最后都是同于ResourceManager的getResources方法获取到的Resources 实例对象的。