Application 运行上下文环境 Context的创建过程
在android应用程序中,可以使用getApplicationContext()方法来获得应用程序的全局Context,在引用程序的任何位置都可以通过getApplicationContext()方法得到该Context对象,那么这个方法获得的Context在框架中是怎么创建的呢?
图为Application Context 类关系图
从图中可知,Application继承ContextWrapper,ContextWrapper继承Context,ContextImpl也继承Context,ContextImpl是Context的真正实现,mOuterContext对象是Application的实例,它通过ContextImpl类的静态方法setOuterContext()设置值,而mBase对象是一个ContextImpl实例,它通过Application的attach() 方法来被赋值
接下来看一下Application Context是怎么创建的
当启动一个Activity的时候,android系统Framwork框架里的ActivityManagerService核心方法会调入应用程序客户端ActivityThread类的ScheduleLauncherActivity()方法里,下面分析Application Context创建过程,如下图:
scheduleLaunchActivity()防范会通过H类发送一个LAUNCH_ACTIVITY消息,H类继承handler,接下来看H类的定义
private class H extends Handler {
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}
H 类是一个继承handler的ActivityThread的内部类,主要用在ActivityThread内部分发消息,前面发送了LAUNCH_ACTIVITY消息之后,最终系统会分发这个消息进入到H类中的handleMessage()方法中,调用handleLaunchActivity方法继续处理
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
WindowManagerGlobal.initialize();
Activity a = performLaunchActivity(r, customIntent);
...
performLaunchActivity()主要用于创建Application Context和Activity Context,接下来看一下这个方法
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
}
这个方法里面packageInfo是LoadedApk类型的对象,接着调用makeApplication方法继续处理
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
....
}
createAppContext()方法创建了一个ContextImpl的实例,然后又通过newApplication()创建了一个Application的对象app,在newApplication方法中,会把appContext对象作为参数传递到Application中,赋值给ContextWrapper类里的mBase对象,当app对象创建好之后,就调用setOuterContext方法,把app赋值给ContextImpl的mOuterContext变量,最后把app赋值给LoadedApk的全局变量mApplication,mInstrumentation是Instrumentation类型的对象,接下来看一下newApplication方法的实现
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
这个方法首先创建了一个Application类型的对象app,然后调用attach方法把ContextImpl对象context赋值给ContextWrapper类的mBase对象,
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 = base;
}
到此Application Context的创建过程就介绍完了