前言
Activity的啟動有兩種流程,一種是入口Activity的啟動,另外一種就是普通Activity啟動。入口Activity是指應用程序啟動的第一個Activity,它的啟動過程也可以理解為應用程序的啟動過程。普通Activity的流程相對簡單很多,是入口Activity啟動流程中的一部分,所以我們這里只看入口Activity啟動流程。
Launcher請求AMS
前面的文章中知道Launcher啟動后會將已安裝程序的圖標顯示到桌面上,當點擊這個圖標的時候,Launcher就會請求AMS啟動應用。過程如下:

可以看到依次調用了Activity的startActivity和startActivityForResult函數(shù),這里來看看startActivityForResult的代碼:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
} else {
...
}
}
因為入口Activity還沒創(chuàng)建出來,所以mParent是空(如果不為空說明應用已經啟動,則就進入了普通Activity的流程),這樣就執(zhí)行了Instrumentation的execStartActivity方法。
在execStartActivity中會調用ActivityManager的getService方法來獲取AMS的代理對象,然后調用它的startActivity方法,這樣就將啟動請求發(fā)送到AMS中了。
AMS處理請求
在AMS中會對請求進行一系列處理,最終會讓ApplicationThread來處理,這部分時序圖如下:

AMS的startActivity的代碼如下:
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
直接調用了startActivityAsUser,這里通過 UserHandle.getCallingUserId() 獲取了調用者的UserId,AMS就是根據(jù)這個id來確定調用者的權限,如果權限不夠則不能啟動該應用。
在startActivityAsUser中會依次調用ActivityStarter的startActivityMayWait、startActivityLocked和startActivity。這里重點說一下startActivity方法,它的主要代碼如下:
private int startActivity(...) {
...
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
err = ActivityManager.START_PERMISSION_DENIED;
}
}
...
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, container, options, sourceRecord);
if (outActivity != null) {
outActivity[0] = r;
}
...
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask, outActivity);
}
首先判斷caller是否為null,這個caller就是發(fā)起請求的應用進程(因為我們是從Launcher開始的,所以這里就是Launcher)的ApplicationThread對象。
然后看到調用了AMS的getRecordForAppLocked獲取callerApp對象,它是ProcessRecord類型(ProcessRecord這個類用來描述應用程序進程)。
繼續(xù)往下看,接下來創(chuàng)建了一個ActivityRecord對象,與ProcessRecord類似ActivityRecord用來記錄一個Activity的信息。
最后調用了另外一個startActivity方法,在這個方法中會調用startActivityUnchecked方法,這個方法的代碼如下:
private int startActivityUnchecked(...) {
...
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
result = setTaskFromReuseOrCreateNewTask(
taskToAffiliate, preferredLaunchStackId, topStack);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
setTaskToCurrentTopOrCreateNewTask(); //代碼1
}
...
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
...
} else {
...
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); //代碼2
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
...
}
這個方法主要處理與棧管理相關邏輯,在代碼1處的setTaskToCurrentTopOrCreateNewTask方法會創(chuàng)建一個新的TaskRecord,用來描述Activity任務棧,也就是說會創(chuàng)建一個新的Activity任務棧。
然后在代碼2處調用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法,代碼如下:
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
這里判斷如果Activity為null或者不是RESUMED狀態(tài)會調用ActivityStack的resumeTopActivityUncheckedLocked方法。在這個方法中會調用resumeTopActivityInnerLocked,然后會調用ActivityStackSupervisor的startSpecificActivityLocked方法,來重點看看這個方法:
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
可以看到一開始獲取了即將啟動的Activity所在的應用進程,然后判斷這個應用進程是否存在并且已經運行,如果沒運行則直接跳到方法尾部,可以看到這里會調用startProcessLocked啟動應用進程;如果已經運行則進入if語句,可以看到最終執(zhí)行到realStartActivityLocked方法,這個方法的代碼如下:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {
...
try {
...
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
...
} catch (RemoteException e) {
...
}
...
return true;
}
這里app.thread是IApplicationThread,它的實現(xiàn)是ActivityThread的內部類ApplicationThread。這里調用scheduleLaunchActivity就是在目標應用程序的進程中啟動Activity。因為當前在AMS進程中,所以這里就需要通過ApplicationThread來與應用程序進程進行Binder通信,ApplicationThread就可以看作是AMS和應用程序進程的橋梁。

ActivityThread啟動Activity
通過ApplicationThread我們就進入了應用程序進程中,來看看最后這部分的流程是什么樣子的:

ApplicationThread將這個啟動的消息傳給ActivityThread,最后會調用它的handleLaunchActivity,代碼如下:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity a = performLaunchActivity(r, customIntent); //1
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed); //2
...
} else {
......
}
}
代碼1處調用了performLaunchActivity來啟動Activity,并返回得到一個Activity對象。代碼2處則通過handleResumeActivity將這個Activity的狀態(tài)設置為Resume。
接下來看看performLaunchActivity這個方法,這是啟動環(huán)節(jié)一個很重要的節(jié)點,代碼如下:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
ActivityInfo aInfo = r.activityInfo; //1
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, //2
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent(); //3
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent); //4
...
}
} catch (Exception e) {
...
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation); //5
...
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
...
}
//6
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);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//7
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
return activity;
}
代碼1處獲取ActivityInfo,這個info里存儲一些Activity的信息,比如theme和launchMode;代碼3處獲取要啟動Activity的ComponentName,這里存儲著Activity的包名和類名;代碼4則根據(jù)ComponentName創(chuàng)建了要啟動的Activity對象;代碼5調用makeApplication創(chuàng)建Application對象,這個方法內部會調用Application的onCreate方法;代碼6則調用了Activity的attach方法,這個方法中會做一些初始化的工作;最后代碼7調用Instrumentation的callActivityOnCreate來啟動Activity。
allActivityOnCreate中調用了Activity的performCreate方法,而這個方法中會調用Activity的onCreate方法,這樣Activity就啟動起來了。
總結
上面可以看到,入口Activity的啟動會涉及4個進程:Zygote進程,Launcher進程、AMS進程(SystemServer進程)和應用程序進程。
Launcher向AMS請求創(chuàng)建入口Activity,AMS先判斷這個Activity的應用程序進程是否存在并啟動,如果不存在會請求Zygote創(chuàng)建應用程序進程并啟動。應用程序進程啟動后,會通知給AMS, AMS這時候就會請求創(chuàng)建入口Activity并啟動。如圖:

注意:這個過程中,AMS與Zygote是Socket通信,而Launcher與AMS是Binder通信,同樣AMS與應用程序進程也是Binder通信。