请求启动一个Activity时,ActivityManagerService 会通过IPC调周到ActivityThread类的scheduleLaunchActivity()方法。
public final class ActivityThread {
......
private class ApplicationThread extends IApplicationThread.Stub {
......
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
......
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
......
sendMessage(H.LAUNCH_ACTIVITY, r);
}
......
}
......
}
其中该方法有一个ActivityInfo类型的参数 , 这是一 个实现了Parcelable接口的数据类, 它是由AmS创建的, 并通过IPC传递到ActivityThread中的。然后使用这些传入的参数来构建一个ActivityClientRecord对象r , 这是个数据类,代表的就是一个本地Activity对象的记录,ActivityThread内部会为每 一 个Activity创建一 个ActivityClientRecord对象 , 并使用这些数据对象来管理Activity。scheduleLaunchActivity()方法接下来通过H类发送 一 个LAUNCH_ACTIVITY消息, H类 继承于Handler, 下面看看H类的定义。
public final class ActivityThread {
......
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
......
public void handleMessage(Message msg) {
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, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
......
}
......
}
......
}
......
}
从H类的定义可知, 它是
一 个继承Handler的ActivityThread内部类,
主要用
来在ActivityThread内部分发消息。当前面scheduleLaunchActivity()方法里发送了
LAUNCH ACTIVITY 消息之后, 最终系统会分发这个消息进入到H 类中的
handleMessage()方法, 在H类的handleMessage()方法则调用
ActivityThread类的handleLaunchActivity()
方法来继续处理。
public final class ActivityThread {
......
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
......
Activity a = performLaunchActivity(r, customIntent);
......
}
}
handleLaunchActivity()方法首先调用了performLaunchActivity()方法, 这个方法
主要用于创建Application Context和Activity Context。 下面来看看performLaunchActivity()方法如何创建Activity
Context。
public final class ActivityThread {
......
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
......
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
......
} catch (Exception e) {
......
}
try {
//下面创建Appication
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
......
//下面是对Activity的处理
if (activity != null) {
......
appContext.setOuterContext(activity);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
......
}
......
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
.......
}
return activity;
}
performLaunchActivity()方法首先会调用getPackageInfo方法来获取一个LoadedApk对象,这个对象在创建Application时已经保存在ActivityThread的变量中了,可以直接取得。接着调用createBaseContextForActivity方法来创建Activity的context实例,接着创建Activity实例,之后再调用LoadedApk对象的makeApplication方法来创建Application实例,由于进程启动的时候就已经创建了Application对象并保存在LoadedApk对象的mApplication变量中,这里会直接返回这个Application对象。但是,由于LoadedApk对象是弱引用保存的,可能会被回收而需要重新new出来,这将导致新的LoadedApk对象里面的mApplication对象实例为空,此时会在makeApplication方法中重新创建一个Application对象。下面来看看createBaseContextForActivity方法如何创建Activity的ContextImpl实例。
public final class ActivityThread {
......
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
......
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
......
return appContext;
}
......
}
ActivityThread 的 createBaseContextForActivity ()方法通过调用 Contextlmpl 类的
createActivityContext()静态方法, 来创建 Contextlmpl 类实例对象 appContext , 而
createActivityContext ()方法的真正实现就是 new 了 一 个 Contextlmpl 实例。
这
一 步执行完成之后, 回到前面的ActivityThread类的performLaunchActivity()方法
中, 接下来就会调用
Instrumentation
对象的newActivity()方
法用于创建 一 个Activity实例。
public class Instrumentation {
......
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
......
}
cl是 一 个类加载器, className是 一 个Activity 子类的名字, 在应用程序开发中,
都用
一
个子类来继承Activity,所以cl.loadClass(className) .new Instance()会通过反射来创建 一 个
Activity类的实例。子 Activity实例在创建 过程中会调用父类 Activity 的默认构造方
法。由于Activity没有定义自己的构造方法, 因此, 系统会为它提供 一 个默认的构造
方法, 但是, 系统为Activity类提供的默认构造方法什么也没做, 也就是说Activity
类实例在创建的时候, 还没有执行实质性的初始化工作, 这个初始化工作由Activity
的attach()方法完成。
创建完Activity后返回到
performLaunchActivity方法中继续执行,因为activity!=null,所以会接着调用 appContext.setOuterContext(activity)方法,并且将activity实例作为参数传入,这样Contextlmpl实现类实例就会持有一个包装类
ContextWrap类实例,这里就是Activity,以后 Contextlmpl 也可以访问 Activity 中的变量和方法。接着调用Activity的attach方法,这个方法主要是对activity进行初始化,其内部会调用
attachBaseContext
(context)方法,并且将
Contextlmpl类实例作为参数传入,保存在其父类ContextWrap的mBase实例变量中,这样Activity中就持有了Contextlmpl类实例,也就是Activity的Context创建完成。