今天我们来分析下Activity的启动流程,看看Activity是啥时候创建的,窗口是啥时候创建的,Context呢?
我们启动一个Activity时一般是这样的:
Intent intent = new Intent(MainActivity.this, TestActivity.class);
startActivity(intent);
实际上startActivity调用的是Activity类里面的方法,在Activity类中startActivity有多个重载方法,但最后调用的都是startActivityForResult方法
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
//mParent代表的是ActivityGroup,肯定是null的
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
看上面的源码,这里需要注意的是这里会走mParent==null这个分支。mParent代表的是ActivityGroup,也就是一个Activity里面再嵌套Activity,这种方式已经被Fragment替代了。
这里的mMainThread就是ActivityThread,而mMainThread.getApplicationThread()就是ActivityThread的内部类ApplicationThread。ActivityThread和ApplicationThread在Activity的启动过程中发挥了很重要的作用。
//Instrumentation.class
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//这里可以看到ApplicationThread其实是个Binder
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//调用ActivityManagerNative的getDefault方法返回ActivityManagerService
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//这个方法用于检查Activity的启动结果,如果启动失败是抛出相应的异常
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
从Instrumentation的execStartActivity源码可以看到,ApplicationThread其实是个Binder,它主要是供后面从ActivityManagerService的进程回调到应用的进程。同时启动Activity的过程通过Binder机制转到了ActivityManagerService。
ActivityManagerService中的Activity的启动过程就相对复杂很多,需要经过很多的跳转和处理,比如需要判断要启动的Activity的任务栈是否存在,不存在的话要创建任务栈;暂停当前的Activity,以便当前待启动的Activity可以获取焦点等。这里我们就不跟进去看源码了,容易绕晕。
ActivityManagerService做好自己的事儿以后,就会调用我们传过去的Binder对象ApplicationThread的scheduleLaunchActivity来将进程切换到当前应用的进程,以便继续完成启动Activity的任务。
//ApplicationThread.class
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
...) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
ActivityClientRecord中保存了要启动的Activity的信息。由于ApplicationThread是一个Binder,所以scheduleLaunchActivity是运行在Binder线程池中的,需要通过Handler将线程切换到ActivityThread的线程中去。而上面源码中的H就是ActivityThread中的Handler。
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
public static final int STOP_ACTIVITY_SHOW = 103;
public static final int STOP_ACTIVITY_HIDE = 104;
public static final int RECEIVER = 113;
public static final int CREATE_SERVICE = 114;
public static final int SERVICE_ARGS = 115;
public static final int STOP_SERVICE = 116;
...
String codeToString(int code) {
if (DEBUG_MESSAGES) {
switch (code) {
case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
case RECEIVER: return "RECEIVER";
case CREATE_SERVICE: return "CREATE_SERVICE";
case SERVICE_ARGS: return "SERVICE_ARGS";
case STOP_SERVICE: return "STOP_SERVICE";
...
}
}
return Integer.toString(code);
}
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, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}
可以看到这个Handler里面大量的跟四大组件有关的方法,其他的组件的一些启动停止等都会回调到这里,由这个Handler处理。
我们看到Handler H对LAUNCH_ACTIVITY的处理是通过ActivityThread的handleLaunchActivity方法
//ActivityThread.class
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
从源码中我们可以看到启动Activity的过程最后由performLaunchActivity来完成,完成以后就会调用handleResumeActivity方法来调用启动的Activity的onResume方法。
performLaunchActivity主要完成了以下几件事:
(1)从ActivityClientRecord中获取待启动的Activity组件的信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
(2)通过Instrumentation类的newActivity方法,利用类加载器来创建Activity
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
newActivity方法直接用类加载器加载类
//newActivity方法直接用类加载器加载类
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
(3)调用LoadApk的makeApplication创建Application对象,如果Application对象已经存在则不会重新创建
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
//如果已经存在mApplication,则不创建,所以一个应用只有一个Application
if (mApplication != null) {
return mApplication;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
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)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
//调用Application的OnCreate方法
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
...
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return app;
}
(4)创建ContextImpl对象并通过Activity的attach方法完成关联和其他初始化操作
//调用createBaseContextForActivity方法创建ContextImpl
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
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);
Activity的attach方法会完成绑定ContextImpl,创建Window,关联Application等任务
//Activity.class
final void attach(Context context, ActivityThread aThread,
...
Window window) {
//绑定ContextImpl
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
//创建Window并设置回调监听
mWindow = new PhoneWindow(this, window);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}
mUiThread = Thread.currentThread();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mIdent = ident;
mApplication = application;
mIntent = intent;
...
}
(5)调用Activity的onCreate方法
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
这样Activity就启动完毕了。
总结
通过对在应用里面启动新的Activity的过程进行源码跟踪,我们发现这里面主要涉及到几个类:Activity、ActivityThread、ApplicationThread、ActivityManagerService。
(1)Activity是我们发起启动新的Activity的入口,也是最后完成Activity操作结束的地方。我们通过Activity的startActivity发起启动新Activity的请求,最后通过Activity的attach方法完成Context的绑定和窗口Window的创建和绑定。
(2)ActivityThread是启动Activity的处理者,也是一个中间人的角色,通过调用其他几个类完成启动Activity的任务。它首先通过Binder机制调用ActivityManagerService完成Activity相关的系统级的操作,比如任务栈,暂停其他Activity等,然后通过内部的Binder类ApplicationThread接收ActivityManagerService的进程间请求,将启动的操作重新转回到当前应用进程。接着通过调用Instrumentation和LoadApk的相关方法完成加载Activity类和Application的任务。最后调用Activity的attach方法完成一系列的绑定操作。
(3)ApplicationThread是一个Binder类,用于和ActivityManagerService的进程间通信。
(4)ActivityManagerService是系统的一个服务,用于管理Activity的状态和相关信息,比如任务栈等。
如果是直接点击桌面的应用图标启动应用呢?其实这个过程和启动Activity类似,都是需要启动一个Activity。不过启动应用启动的是应用的入口Activity,同时是从桌面应用启动另一个应用程序的Activity,所以过程肯定会多一些步骤,比如要找到应用中的入口Activity,创建新的应用程序进程,要创建任务栈,要移除桌面的焦点等。等这些准备工作都好了以后,后面就相当于是启动一个Activity的过程了。有兴趣的童鞋可以研究一下。
欢迎关注我的微信公众号,和我一起每天进步一点点!