Android应用程序窗口(Activity)的运行上下文环境(Context)的创建过程分析
在前文中,我们简要介绍了Android应用程序窗口的框架。Android应用程序窗口在运行的过程中,需要访问一些特定的资源或者类。这些特定的资源或者类构成了Android应用程序的运行上下文环境,Android应用程序窗口可以通过一个Context接口来访问它,这个Context接口也是我们在开发应用程序时经常碰到的。在本文中,我们就将详细分析Android应用程序窗口的运行上下文环境的创建过程。 www.zzzyk.com
在前面Android应用程序窗口(Activity)实现框架简要介绍和学习计划一文中提到,Android应用程序窗口的运行上下文环境是通过ContextImpl类来描述的,即每一个Activity组件都关联有一个ContextImpl对象。ContextImpl类继承了Context类,它与Activity组件的关系如图1所示:
图1 ContextImpl类与Activity类的关系图
这个类图在设计模式里面就可以称为装饰模式。Activity组件通过其父类ContextThemeWrapper和ContextWrapper的成员变量mBase来引用了一个ContextImpl对象,这样,Activity组件以后就可以通过这个ContextImpl对象来执行一些具体的操作,例如,启动Service组件、注册广播接收者和启动Content Provider组件等操作。同时,ContextImpl类又通过自己的成员变量mOuterContext来引用了与它关联的一个Activity组件,这样,ContextImpl类也可以将一些操作转发给Activity组件来处理。
在前面Android应用程序启动过程源代码分析一文中,我们已经详细分析过一个Activity组件的启动过程了。在这个启动过程中,最后一步便是通过ActivityThread类的成员函数performLaunchActivity在应用程序进程中创建一个Activity实例,并且为它设置运行上下文环境,即为它创建一个ContextImpl对象。接下来,我们就从ActivityThread类的成员函数performLaunchActivity开始,分析一个Activity实例的创建过程,以便可以从中了解它的运行上下文环境的创建过程,如图2所示:
图2 Android应用程序窗口的运行上下文环境的创建过程
这个过程一共分为10个步骤,接下来我们就详细分析每一个步骤。
Step 1. ActivityThread.performLaunchActivity
[java]
public final class ActivityThread {
......
Instrumentation mInstrumentation;
......
private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
ComponentName component = r.intent.getComponent();
......
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
......
} catch (Exception e) {
......
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
......
if (activity != null) {
ContextImpl appContext = new ContextImpl();
......
appContext.setOuterContext(activity);
......
Configuration config = new Configuration(mConfiguration);
......
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstance,
r.lastNonConfigurationChildInstances, config);
......
mInstrumentation.callActivityOnCreate(activity, r.state);
......
}
......
} catch (SuperNotCalledException e) {
......
} catch (Exception e) {
......
}
return activity;
}
}
这个函数定义在文件frameworks/base/core/java/android/app/ActivityThread.java中。
要启动的Activity组件的类名保存在变量component。有了这个类名之后,函数就可以调用ActivityThread类的成员变量mInstrumentation所描述一个Instrumentation对象的成员函数newActivity来创建一个Activity组件实例了,并且保存变量activity中。Instrumentation类是用来记录应用程序与系统的交互过程的,在接下来的Step 2中,我们再分析它的成员函数newActivity的实现。
创建好了要启动的Activity组件实例之后,函数接下来就可以对它进行初始化了。初始化一个Activity组件实例需要一个Application对象app、一个ContextImpl对象appContext以及一个Configuration对象config,它们分别用来描述该Activity组件实例的应用程序信息、运行上下文环境以及配置信息。这里我们主要关心运行上下文环境的创建过程,即ContextImpl对象appContext的创建过程,这个过程我们在接下来的Step 4中再分析。
ContextImpl对象appContext创建完成之后,函数就会调用它的成员函数setOuterContext来将与它所关联的Activity组件实例activity保存在它的内部。这样,ContextImpl对象appContext以后就可以访问与它所关联的Activity组件的属性或者方法。在接下来的Step 5中,我们再分析ContextImpl类的成员函数setOuterContext
补充:移动开发 , Android ,