概述
本文主要內(nèi)容是從源碼角度進行Activity啟動流程的分析叉谜。由于整個啟動的過程非常長并且代碼非常多秸讹,同時受限于筆者的水平庆猫,所以本文不會細(xì)致到解釋每一行的代碼的具體作用,只能抽取處關(guān)鍵部分的代碼就主體流程進行分析岛抄,如有錯誤之處别惦,希望批評指出。
行文脈絡(luò)
由于本文會非常長夫椭,為了方便讀者的理解掸掸,首先給出筆者的行文脈絡(luò)。本文主要沿著:在應(yīng)用程序1的Activity A內(nèi)打開另一個應(yīng)用程序2的Activity B蹭秋,這一思路進行寫作扰付。流程概括如下:
①Activity A發(fā)起一個啟動Activity B的請求(對應(yīng)主流程分析1~2)
②AMS為啟動Activity B做準(zhǔn)備 (對應(yīng)主流程分析3~4)
③暫停Activity A(對應(yīng)主流程分析5~7)
④應(yīng)用程序1通知AMS完成了暫停操作,AMS處理該消息(對應(yīng)主流程分析8)
⑤AMS啟動一個新的進程感凤,即應(yīng)用程序2(對應(yīng)主流程分析9~11)
⑥在新進程內(nèi)完成Activity B的創(chuàng)建悯周、啟動操作(對應(yīng)主流程分析12~13)
限于文章的篇幅粒督,本文只介紹①~③陪竿,剩下的內(nèi)容會在下一篇文章給出。
時序圖
下面先給出與代碼分析相一致的時序圖,通過該時序圖能更好地理解Activity的啟動流程族跛,讀者可以結(jié)合該時序圖與下面的代碼分析一起看闰挡。
主流程分析
1、Activity#startActivityForResult()方法:
無論從Launcher或者Activity打開一個新的Activity礁哄,都會調(diào)用startActivity()方法长酗,而這些重載方法最終都會調(diào)用startActivityForResult
方法,代碼如下:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
//把啟動一個Activity的行為交給Instrumentation處理
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;
}
} //省略部分代碼..
}
2桐绒、Instrumentation#execStartActivity()方法:
在該方法內(nèi)夺脾,主要是通過ActivityManagerService來啟動一個Activity,而該ActivityManagerService是運行在一個獨立的進程空間的茉继,它負(fù)責(zé)整個Android系統(tǒng)內(nèi)的所有Activity的創(chuàng)建過程咧叭。因此,當(dāng)前APP進程需要與ActivityManagerService進程進行跨進程通信烁竭,這就需要借助Binder機制了菲茬。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//省略部分代碼,只看關(guān)鍵部分..
//IApplicationThread有點特殊派撕,它是IBinder對象婉弹,用于跨進程通信
IApplicationThread whoThread = (IApplicationThread) contextThread;
//ActivityMonitor主要配合InstrumentationTest一起使用,用于統(tǒng)計
//相匹配的Activity啟動次數(shù)终吼,與APP測試有關(guān)镀赌,這里省略不談
if (mActivityMonitors != null) {
//....
}
try {
//獲取ActivityManagerService代理對象,調(diào)用startActivity()方法衔峰,
//這里實際上通過Binder跨進程調(diào)用了ActivityManagerService的方法
int result = ActivityManager.getService() //2-1代碼
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
2-1佩脊、我們看看ActivityManager#getService()代碼做了什么工作:
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
//如果進程不同,則獲取一個IActivityManager代理對象
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
顯然垫卤,這是一個典型的AIDL使用過程威彰。IActivityManager實際上是一個AIDL文件,編譯器會幫我們把AIDL文件解析成一個Java文件穴肘,也即是IActivityManager.java歇盼,通過AIDL的方式我們能方便地實現(xiàn)Binder通信。而Binder通信的內(nèi)部調(diào)用過程评抚,這里不展開來說豹缀,我們只關(guān)注大體的邏輯即可。上面的IActivityManager.Stub
是在編譯器生成的一個內(nèi)部類慨代,而它的asInterface()
方法則是根據(jù)當(dāng)前進程是否與IBinder處于同一進程邢笙,如果是,則直接返回IActivityManager的實例侍匙,否則會返回一個IActivityManager.Stub.Proxy的代理對象氮惯。由于我們的App與AMS肯定不是同一進程,所以這里獲得的是AMS的遠(yuǎn)程代理。(可以參考設(shè)計模式中的代理模式)
回到代碼2-1往下看妇汗,在獲取了IActivityManager的實例后(實際上是代理對象)帘不,會調(diào)用它的startActivity(params..)
方法,在這個過程中杨箭,進行了基于Binder跨進程通信寞焙,把一系列的params參數(shù)傳遞給AMS,此時AMS的startActivity(params..)被調(diào)用了互婿,我們往下看它的代碼捣郊。
3、ActivityManagerService#startActivity()
需要注意的是慈参,AMS的代碼在/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 目錄下模她,這是frameworks層的源碼,在sdk下是看不到的懂牧,所以我們需要下載Android的源碼或者在網(wǎng)上查看侈净。(筆者這里通過Android Frameworks源碼來查看的,有興趣的可以自行前往查看)僧凤。
當(dāng)代碼運行到這里的時候畜侦,我們可以知道以下兩個信息:
①從架構(gòu)的層面來看,已經(jīng)從應(yīng)用層來到了frameworks層躯保。
②從進程的層面來看旋膳,當(dāng)前進程已經(jīng)是AMS所在的進程。
好了途事,我們繼續(xù)來分析源碼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());
}
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivity");
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
//ActivityStarter內(nèi)部有一個Request验懊,封裝了請求的具體信息
.setCaller(caller) //設(shè)置Caller為IApplicationThread對象,這個實際上是代理對象
.setCallingPackage(callingPackage) //設(shè)置包名
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
可以看到,方法的參數(shù)已經(jīng)包含了一系列啟動Activity所需要的參數(shù)尸变,而在最后又調(diào)用了ActivityStartController
的方法來獲取一個ActivityStarter
义图,并把所有的參數(shù)封裝到了ActivityStarter.Request
內(nèi),最后調(diào)用ActivityStarter#execute()
方法來啟動一個Activity的創(chuàng)建過程召烂。
3-1碱工、ActivityStartController#obtainStarter()
我們直接從源碼的注釋來看看ActivityStartController
有什么作用:
/**
* Controller for delegating activity launches.
*
* This class' main objective is to take external activity start requests and prepare them into
* a series of discrete activity launches that can be handled by an {@link ActivityStarter}. It is
* also responsible for handling logic that happens around an activity launch, but doesn't
* necessarily influence the activity start. Examples include power hint management, processing
* through the pending activity list, and recording home activity launches.
*/
public class ActivityStartController {
//...
/**
* @return A starter to configure and execute starting an activity. It is valid until after
* {@link ActivityStarter#execute} is invoked. At that point, the starter should be
* considered invalid and no longer modified or used.
*/
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
}
從源碼注釋可以知道,它一個是委派Activity啟動的控制器奏夫,它管理著一系列的Activity的啟動行為怕篷,并且承擔(dān)著Activity啟動過程的電量提示管理、Home的啟動記錄等的工作酗昼。但它實際上并不涉及Activity啟動的具體邏輯廊谓,它把啟動的邏輯交給了ActivityStarter
來處理了。
3-2麻削、ActivityStarter代碼分析
/**
* Controller for interpreting how and then launching an activity.
*
* This class collects all the logic for determining how an intent and flags should be turned into
* an activity and associated task and stack.
*/
class ActivityStarter {
//ActivityStartController通過該Factory來獲取一個Starter
static class DefaultFactory implements Factory {
//對象池內(nèi)只有3個活躍對象蒸痹,也即是ActivityStarter被設(shè)計成可循環(huán)利用的
private final int MAX_STARTER_COUNT = 3;
private SynchronizedPool<ActivityStarter> mStarterPool =
new SynchronizedPool<>(MAX_STARTER_COUNT);
//省略部分代碼...
@Override
public ActivityStarter obtain() {
ActivityStarter starter = mStarterPool.acquire();
if (starter == null) {
starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
}
return starter;
}
@Override
public void recycle(ActivityStarter starter) {
starter.reset(true /* clearRequest*/);
mStarterPool.release(starter);
}
}
//Request類封裝了啟動Activity所需要的一切參數(shù)
private static class Request {
//省略...
}
/**
* Starts an activity based on the request parameters provided earlier.
* @return The starter result.
*/
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
}else {
//...
}
} finally {
onExecutionComplete(); //最后舔示,會調(diào)用ActivityStartController的對應(yīng)方法,進行Starter的釋放回收
}
}
//省略...
}
ActivityStarter
是具體的Activity啟動器电抚,它的內(nèi)部類Request
封裝了啟動Activity的一系列信息,而ActivityStarter
被設(shè)計成了一個對象池的形式竖共,是可以復(fù)用的蝙叛,因為Android系統(tǒng)可能會頻繁地啟動Activity,所以啟動器設(shè)計出復(fù)用的形式可以減少開銷公给。當(dāng)execute()
被調(diào)用的時候借帘,該啟動器便開始執(zhí)行啟動一個Activity的具體流程,即調(diào)用startActivityMayWait(params)
方法淌铐。
我們順著代碼繼續(xù)往下看肺然,即ActivityStarter#startActivityMayWait()
:
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup) {
//由于代碼很長,這里做了很多刪減腿准,只關(guān)注主體部分..
// Collect information about the target of the Intent.
//這里里面調(diào)用了PackageManagerService的方法來解析Intent.
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,0 /* matchFlags */,
computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));
//接著將Intent的信息解析為ActivityInfo
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
synchronized (mService) {
final ActivityStack stack = mSupervisor.mFocusedStack;
stack.mConfigWillChange = globalConfig != null
&& mService.getGlobalConfiguration().diff(globalConfig) != 0;
final long origId = Binder.clearCallingIdentity(); //設(shè)置callingPid和callingUid為當(dāng)前進程標(biāo)識
final ActivityRecord[] outRecord = new ActivityRecord[1];
//進一步調(diào)用startActivity(params..)方法,24個參數(shù)的重載方法
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup);
Binder.restoreCallingIdentity(origId); //設(shè)置callingPid和callingUid為跨進程調(diào)用該方法的進程標(biāo)識
if (outResult != null) {
outResult.result = res;
final ActivityRecord r = outRecord[0];
//根據(jù)res來判斷Activity的啟動狀態(tài)來做進一步處理
switch(res) {
//Activity正常啟動
case START_SUCCESS: {
mSupervisor.mWaitingActivityLaunched.add(outResult);
do {
try {
mService.wait();
} catch (InterruptedException e) {
}
} while (outResult.result != START_TASK_TO_FRONT
&& !outResult.timeout && outResult.who == null);
if (outResult.result == START_TASK_TO_FRONT) {
res = START_TASK_TO_FRONT;
}
break;
}
//Activity并不是真正的啟動际起,因為該Intent對應(yīng)的Activity已在棧頂
case START_DELIVERED_TO_TOP: {
//省略..
break;
}
//Activity并不是真正的啟動,而是把已有的Activity帶到了前臺
case START_TASK_TO_FRONT: {
//省略...
break;
}
}
}
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
return res;
}
}
/**
* 經(jīng)過一系列startActivity()重載方法的調(diào)用吐葱,最后會調(diào)用該方法
*/
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
int result = START_CANCELED;
try {
mService.mWindowManager.deferSurfaceLayout(); //通知WindowManager暫停布局
//進一步調(diào)用startActivityUnchecked(params..)方法
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
//如果Activity沒有啟動成功街望,那么關(guān)閉它,否則可能會出現(xiàn)問題
final ActivityStack stack = mStartActivity.getStack();
if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
null /* intentResultData */, "startActivity", true /* oomAdj */);
}
mService.mWindowManager.continueSurfaceLayout(); //通知WindowManager繼續(xù)布局
}
//Activity啟動后還有一些工作要處理
postStartActivityProcessing(r, result, mTargetStack);
return result;
}
/**
* 該方法處理了Intent的各種flags以及Activity的啟動模式
*/
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
//初始化信息
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
//計算LaunchingTaskFlags弟跑,對flag進行合法性處理
computeLaunchingTaskFlags();
//如果Task已經(jīng)結(jié)束了灾前,要做出處理,然后獲得一個新的Task
computeSourceStack();
mIntent.setFlags(mLaunchFlags);
ActivityRecord reusedActivity = getReusableIntentActivity(); //獲取當(dāng)前Task的Activity
//...
//如果Task內(nèi)已有Activity孟辑,結(jié)合即將啟動Activity的launch mode做出處理
if (reusedActivity != null) {
//省略具體處理過程暫不作分析哎甲,這里與Activity的啟動模式有關(guān)
//..
}
//如果Activity的包名不存在,則啟動失敗
if (mStartActivity.packageName == null) {
//省略..
return START_CLASS_NOT_FOUND;
}
//如果即將啟動的Activity與棧頂?shù)腁ctivity相同饲嗽,那么判斷是否需要繼續(xù)啟動
final ActivityStack topStack = mSupervisor.mFocusedStack;
final ActivityRecord topFocused = topStack.getTopActivity();
final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
if (dontStart) {
//省略...
return START_DELIVERED_TO_TOP; //這里的返回值表示棧頂就是需要啟動的Activity
}
//...
//權(quán)限認(rèn)證
mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
//...
//代碼3-3炭玫,見下面分析
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
//mDoResume為true,從函數(shù)參數(shù)傳遞進來的
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
//告訴WindowManager該Activity要做轉(zhuǎn)場動作了
mService.mWindowManager.executeAppTransition();
} else {
//代碼4-1:第一次啟動時貌虾,會在這里進行Activity的啟動
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
}
return START_SUCCESS;
}
從函數(shù)調(diào)用棧來看:startActivityMayWait(params..) -> startActivity(params.. ) -> startActivityUnchecked(params..)
其中省略了若干個重載方法础嫡,這是已經(jīng)是很深層次的調(diào)用棧了,代碼也難以理解酝惧,因此我們很難對每行代碼進行詳細(xì)的分析也沒有這個必要晚唇,我們要善于利用奧卡姆剃刀平项,抽出主干部分進行分析即可接癌,我們的關(guān)注點在理解Activity的啟動過程及其有關(guān)的類的作用,而在此過程有關(guān)的Activity launchMode和Flag等可以不做分析荔燎。
上面的代碼揭示了,一個Activity如果要啟動座享,要結(jié)合任務(wù)棧Task和Activity的啟動模式來進行綜合的處理,比如新建一個棧又或者棧內(nèi)復(fù)用等模式的處理诗箍。我們來關(guān)注上面標(biāo)注出來的代碼3-3滤祖,看看它內(nèi)部做了什么工作。
3-3汤求、ActivityStack#startActivityLocked(params...)
void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
boolean newTask, boolean keepCurTransition, ActivityOptions options) {
TaskRecord rTask = r.getTask();
final int taskId = rTask.taskId;
//這里把Activity添加到Stack的頂部
if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
// Last activity in task had been removed or ActivityManagerService is reusing task.
// Insert or replace.
// Might not even be in.
insertTaskAtTop(rTask, r);
}
TaskRecord task = null;
if (!newTask) {
//如果該Task是已存在的裤唠,那么要找到這個Task
//下面的標(biāo)志位用來表示找到的Task是否是前臺Task
boolean startIt = true;
//mTaskHistory最后的元素就是最前面的Task
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
task = mTaskHistory.get(taskNdx);
if (task.getTopActivity() == null) {
// All activities in task are finishing.
continue;
}
if (task == rTask) {
//要創(chuàng)建的Activity所在的Task不在前臺
if (!startIt) {
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
+ task, new RuntimeException("here").fillInStackTrace());
r.createWindowContainer();
ActivityOptions.abort(options);
return;
}
break;
} else if (task.numFullscreen > 0) {
startIt = false;
}
}
}
final TaskRecord activityTask = r.getTask();
task = activityTask;
if (!isHomeOrRecentsStack() || numActivities() > 0) {
//如果Activity被設(shè)置為沒有進場動畫效果
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
mStackSupervisor.mNoAnimActivities.add(r);
} else {
//Activity有動畫效果
int transit = TRANSIT_ACTIVITY_OPEN;
//省略...
//通知WindowManager來準(zhǔn)備轉(zhuǎn)場效果
mWindowManager.prepareAppTransition(transit, keepCurTransition);
mStackSupervisor.mNoAnimActivities.remove(r);
}
//如果Activity啟動時,它的Task不在前臺坦辟,確保該Activity是可見的
if (r.mLaunchTaskBehind) {
r.setVisibility(true);
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
}
}
從上面代碼的邏輯可以看出锉走,主要是涉及了窗口的處理,即WindowManager,比如該Activity有沒有進場動畫的標(biāo)志位等疮绷。因為啟動一個Activity時,是WindowManager和ActivityManager協(xié)同工作的冬骚,所以這里主要邏輯是通過通知窗口管理者來進行Window Container的創(chuàng)建。當(dāng)然只冻,具體邏輯還是很復(fù)雜的庇麦,這里就不再深究了喜德,讓我們回到上一個方法,開始閱讀4-1的代碼。
4-1秕豫、ActivityStackSupervisor#resumeFocusedStackTopActivityLocked(params...)
創(chuàng)建一個Activity祠墅,并不只是創(chuàng)建一個可視化的視圖而已,它背后任務(wù)棧的這一重要的操作歌径,因此打開一個Activity的流程很復(fù)雜饵隙,其函數(shù)的調(diào)用棧很深,目前我們來到了ActivityStackSupervisor的地盤沮脖,我們來看看這個方法:
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
//省略..
//如果當(dāng)前Stack位于前臺
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
//若Stack不在前臺
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || !r.isState(RESUMED)) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
邏輯還是很簡單金矛,ActivityStackSupervisor又把打開Activity的任務(wù)交給了一個具體的ActivityStack芯急,因為在之前的代碼中我們把一個即將啟動的Activity放到了這個Stack里面,現(xiàn)在我們就要對它進行啟動工作驶俊,我們繼續(xù)往下來看它的代碼娶耍。
4-2、ActivityStack#resumeTopActivityUncheckedLocked(params..)
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
//如果當(dāng)前正在重新啟動一個Activity饼酿,那么跳過
if (mStackSupervisor.inResumeTopActivity) {
return false;
}
boolean result = false;
try {
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
//...
}
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
進一步調(diào)用了resumeTopActivityInnerLocked(params..)
榕酒,我們來繼續(xù)看這個方法。
4-3故俐、ActivityStack#resumeTopActivityInnerLocked(params..)
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
//下面省略了大量代碼想鹰,僅保留主要邏輯
//從當(dāng)前棧頂取出正在啟動的Activity
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
//...
// mResumedActivity是當(dāng)前正在運行的Activity,即處于Resumed狀態(tài)的药版,
//而next是我們放到了棧頂正在啟動的Activity辑舷,注意二者的區(qū)別。
//如果二者相等槽片,那么不做任何改變
if (mResumedActivity == next && next.isState(RESUMED)
&& mStackSupervisor.allResumedActivitiesComplete()) {
//...
return false;
}
//如果屏幕關(guān)閉了何缓,沒有Activity需要啟動,并且棧頂?shù)腁ctivity已經(jīng)暫停还栓,不做改變
if (shouldSleepOrShutDownActivities()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
//...
return false;
}
//...
//確保該Activity的狀態(tài)是正確的碌廓,從等待停止隊列移除等
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
//當(dāng)前有Activity正在執(zhí)行pause操作,return
if (!mStackSupervisor.allPausedActivitiesComplete()) {
//...
return false;
}
//暫停后備堆棧中的所有Activity
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
//代碼5-1剩盒、暫停當(dāng)前處于Resumed狀態(tài)的Activity
pausing |= startPausingLocked(userLeaving, false, next, false);
}
//與WindowManager交互谷婆,確定Activity的啟動動畫
boolean anim = true;
if (prev != null) {
if (prev.finishing) {
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare close transition: prev=" + prev);
if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
anim = false;
mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
} else {
mWindowManager.prepareAppTransition(prev.getTask() == next.getTask()
? TRANSIT_ACTIVITY_CLOSE
: TRANSIT_TASK_CLOSE, false);
}
prev.setVisibility(false);
}
} else {
//...
}
mStackSupervisor.mNoAnimActivities.clear();
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
//...
} else {
//代碼8-4
//該方法實際上是真正啟動一個Activity的地方,但這里的調(diào)用不會生效
//因為辽聊,該方法的內(nèi)部會進行一次判斷:是否有Activity處于未暫停的狀態(tài)
//上面我們跨進程進行了Activity的暫停波材,在Activity未全部暫停之前,該方法都不會真正被調(diào)用身隐。
//這里的調(diào)用應(yīng)該是適用于這種情況:別的Activity全部處于暫停狀態(tài)廷区,能直接啟動新的Activity了
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
從上面代碼的邏輯來看,主要是先執(zhí)行5-1的代碼贾铝,暫停當(dāng)前處于Resumed狀態(tài)的Activity隙轻,然后在最后真正地去啟動當(dāng)前棧頂就緒的Activity。下面垢揩,我們就先來查看怎么處理暫停Activity的邏輯玖绿,接著再看怎么處理啟動Activity的邏輯。
5-1叁巨、ActivityStack#startPausingLocked(params..)
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
//省略部分代碼...
ActivityRecord prev = mResumedActivity;
if (prev == null) {
if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed");
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
return false;
}
if (prev == resuming) {
Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
return false;
}
if (prev.app != null && prev.app.thread != null) {
try {
//代碼5-2斑匪、調(diào)用LifecycleManager#scheduleTransaction方法...
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
}
}
}
通過mService#getLifecycleManager()
獲得了LifecycleManager,這里的mService
就是AMS锋勺,而LifecycleManager實際上是類ClientLifecycleManager蚀瘸,它的代碼位于/frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java
5-2狡蝶、ClientLifecycleManager#scheduleTransaction(params..)
/**
* Schedule a single lifecycle request or callback to client activity.
* @param client Target client.
* @param activityToken Target activity token.
* @param stateRequest A request to move target activity to a desired lifecycle state.
* @throws RemoteException
*
* @see ClientTransactionItem
*/
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
@NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
stateRequest);
scheduleTransaction(clientTransaction);
}
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
上面的邏輯很清晰,先獲得了一個ClientTransaction
對象贮勃,然后再調(diào)用它的schedule()
方法贪惹,最后進行了ClientTransaction
對象的回收。ClientTransaction
封裝了一系列的請求信息寂嘉,即我們的暫停Activity的所有信息都封裝到了它的內(nèi)部奏瞬,同時它實現(xiàn)了Parcelable
接口,表示可序列化的泉孩,這說明它肯定是用于跨進程傳輸?shù)膶ο笈鸲耍覀兺驴创a。
5-3寓搬、ClientTransaction#schedule()
代碼文件在/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/**
* Schedule the transaction after it was initialized. It will be send to client and all its
* individual parts will be applied in the following sequence:
* 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
* that needs to be done before actually scheduling the transaction for callbacks and
* lifecycle state request.
* 2. The transaction message is scheduled.
* 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
* all callbacks and necessary lifecycle transitions.
*/
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
從方法的注釋我們可以知道:
①一次請求會先調(diào)用ClientTransaction#preExecute(ClientTransactionHandler)
②然后執(zhí)行這個請求
③接著調(diào)用TransactionExecutor#execute(ClientTransaction)
方法里面進行了mClient#scheduleTransaction
這一調(diào)用珍昨,這里的mClient
其實就是IApplicationThread
,它實際上是一個代理對象订咸,繼承了IBinder曼尊,表示我們的APP酬诀,主要用于跨進程通信脏嚷。這里實際上是一次跨進程調(diào)用,此時瞒御,從AMS所在的進程切換到了我們的應(yīng)用進程父叙。
6-1、IApplicationThread#scheduleTransaction(transaction)
IApplicationThread
是ActivityThread的一個內(nèi)部類肴裙,我們從那里尋找它的方法scheduleTransaction(transaction)
趾唱。
public final class ActivityThread extends ClientTransactionHandler {
//...
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
//...
}
}
可以看到,在該方法的內(nèi)部進一步調(diào)用了ActivityThread#scheduleTransaction()
方法蜻懦,實際上這里交給了ActivityThread
的父類ClientTransactionHandler
來處理了甜癞。需要注意的是:這里傳遞過來的ClientTransaction
是跨進程通信過程中反序列化生成的對象。
6-2宛乃、ClientTransactionHandler#scheduleTransaction(transaction)
public abstract class ClientTransactionHandler {
// Schedule phase related logic and handlers.
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this); //代碼6-3
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); //代碼6-4
}
//...
}
6-3念秧、ClientTransaction#preExecute(ClientTransactionHandler)
前面5-3有提到過會先調(diào)用preExecute方法痹栖,這里得到了印證。我們來看ClientTransaction
的preExecute
方法。
public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
if (mActivityCallbacks != null) {
final int size = mActivityCallbacks.size();
for (int i = 0; i < size; ++i) {
mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
}
}
if (mLifecycleStateRequest != null) {
mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
}
}
這里主要是進行各種回調(diào)的調(diào)用止吐,就不繼續(xù)展開說了。
6-4见坑、ActivityThread#sendMessage(params..)
繼續(xù)執(zhí)行代碼6-4菇肃,這里調(diào)用了sendMessage
方法,在ClientTransactionHandler
中該方法被標(biāo)注為抽象方法酸些,具體實現(xiàn)是在ActivityThread
內(nèi)宰译。實際上檐蚜,ActivityThread
內(nèi)部的H
繼承了Handler
,用于處理各種消息囤屹。這也就是主線程的消息循環(huán)熬甚。我們直接來看H
的代碼:
public final class ActivityThread extends ClientTransactionHandler {
//...
class H extends Handler {
//一系列消息常量的定義..
public static final int EXECUTE_TRANSACTION = 159;
public void handleMessage(Message msg) {
//根據(jù)不同的消息類型進行不同的處理
switch (msg.what) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
break;
}
}
}
}
這里把處理的邏輯交由給TransactionExecutor
來完成,然后進行ClientTransaction
的回收肋坚。
7-1乡括、TransactionExecutor#execute(ClientTransaction)
TransactionExecutor
可以理解為一個執(zhí)行器,專門用于執(zhí)行各種ClientTransaction
智厌。
/**
* Resolve transaction.
* First all callbacks will be executed in the order they appear in the list. If a callback
* requires a certain pre- or post-execution state, the client will be transitioned accordingly.
* Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
* either remain in the initial state, or last state needed by a callback.
*/
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
方法內(nèi)部首先執(zhí)行executeCallbacks(transaction)
诲泌,由于對于Pause狀態(tài)來說,并沒有添加任何callback铣鹏,所以我們先省略該方法敷扫,接著來看executeLifecycleState(transaction)
。
7-2诚卸、TransactionExecutor#executeLifecycleState(transaction)
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
//根據(jù)之前的代碼邏輯葵第,這里的lifecycleItem實際上是PauseLifecycleItem.
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
final IBinder token = transaction.getActivityToken();
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
//把ActivityClientRecord的狀態(tài)切換到target狀態(tài),這里是pause合溺,表示把Activity切換到暫停狀態(tài)
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
private void cycleToPath(ActivityClientRecord r, int finish,
boolean excludeLastState) {
final int start = r.getLifecycleState();
//計算從start->finish的狀態(tài)變化路徑
//比如:onCreate->onResume的變化路徑有:onStart卒密、onResume等(不包括初始狀態(tài))
//該方法很簡單,讀者可以自行去看
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path); //把該Activity的狀態(tài)沿著這個路徑進行切換
}
/** 該方法把Activity的狀態(tài)沿著路徑進行切換 */
private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r.token, false /* show */,
0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
上面的代碼邏輯還是很清晰的棠赛,主要是先計算出Activity由當(dāng)前狀態(tài)切換到目標(biāo)狀態(tài)所需要走的路徑哮奇,然后遍歷這個路徑上的每一個狀態(tài),把Activity依次切換到該狀態(tài)睛约,當(dāng)遍歷到最后一個狀態(tài)時鼎俘,Activity便完成了狀態(tài)的切換。上面代碼的最后辩涝,又把具體邏輯交給了mTransactionHandler
來處理贸伐,實際上這里的mTransactionHandler
就是ActivityThread
,它繼承了TransactionHandler
怔揩。因此我們到ActivityThread
里面找相應(yīng)的方法捉邢。
7-3、ActivityThread#handlePauseActivity(params..)
因為我們的目標(biāo)狀態(tài)是Pause沧踏,所以會調(diào)用到handlePauseActivity()
方法歌逢。
@Override
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(r, finished, reason, pendingActions);
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
mSomeActivitiesChanged = true;
}
}
/**
* Pause the activity.
* @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise.
*/
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
PendingTransactionActions pendingActions) {
//Honeycomb版本之前的APP在暫停的時候會保存狀態(tài)
final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
if (shouldSaveState) {
callActivityOnSaveInstanceState(r);
}
performPauseActivityIfNeeded(r, reason);
// Notify any outstanding on paused listeners
ArrayList<OnActivityPausedListener> listeners;
synchronized (mOnPauseListeners) {
listeners = mOnPauseListeners.remove(r.activity);
}
int size = (listeners != null ? listeners.size() : 0);
for (int i = 0; i < size; i++) {
listeners.get(i).onPaused(r.activity);
}
//省略...
return shouldSaveState ? r.state : null;
}
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
if (r.paused) {
// You are already paused silly...
return;
}
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
} catch (Exception e) {
//省略..
}
r.setState(ON_PAUSE);
}
經(jīng)過層層的調(diào)用,我們最后發(fā)現(xiàn)調(diào)用到了mInstrumentation.callActivityOnPause(r.activity)
,這個Instrumentation
在上面的代碼解析中也有碰到過翘狱,我們話不多說直接來看它的實現(xiàn):
/**
* Perform calling of an activity's {@link Activity#onPause} method. The
* default implementation simply calls through to that method.
*
* @param activity The activity being paused.
*/
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
到這里已經(jīng)很明朗了秘案,已經(jīng)調(diào)用到了Activity#performPause
方法,即:
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause(); //把暫停事件分發(fā)給Fragment,以觸發(fā)它們暫停
mCalled = false;
onPause(); //調(diào)用onPause阱高,這是我們業(yè)務(wù)邏輯層經(jīng)常接觸的一個生命周期方法
writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
mResumed = false;
//...
}
到現(xiàn)在赚导,已經(jīng)觸發(fā)了onPause()這個生命周期方法,整個暫停的流程就已經(jīng)完成了赤惊。那么當(dāng)一個Activity暫停了吼旧,下一步就是執(zhí)行新Activity的創(chuàng)建流程了。
那么在client端怎么通知server端要執(zhí)行啟動Activity的操作呢未舟?
讓我們把目光定位到代碼7-2的executeLifecycleState(transaction)
方法內(nèi)部圈暗,在方法的最后,會依次執(zhí)行execute
和postExecute
方法裕膀,而這里的lifecycleItem
實際上就是PauseActivityItem
员串。
7-4、PauseActivityItem#postExecute()
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mDontReport) {
return;
}
try {
//通知AMS昼扛,Activity已經(jīng)暫停完畢寸齐,是時候啟動Activity了
ActivityManager.getService().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
這里直接通過Binder跨進程通信,告訴AMS該Activity已經(jīng)暫停了抄谐,AMS可以開始啟動原本打算啟動的Activity了渺鹦。到這一步,APP內(nèi)的工作暫時完成了蛹含,此時進程又會切換到AMS進程內(nèi)毅厚。在開始下一步代碼的閱讀之前,我們需要小結(jié)一下代碼6~7客戶端所做的所有工作挣惰。
小結(jié):APP一直都在進行著主線程的消息循環(huán)卧斟,等待新的消息的到來殴边。此時憎茂,AMS通過Binder跨進程調(diào)用了ApplicationThread的某個方法(如上面的scheduleTransaction
),該方法運行在客戶端的一條子線程上锤岸,然后該方法通過Handler機制竖幔,切換到了主線程。此時在主線程執(zhí)行handleMessage
方法是偷,進而調(diào)用到具體的某一方法拳氢。其中,涉及到Activity生命周期的信息蛋铆、操作被封裝到了ClientTransaction
內(nèi)部馋评,而具體的每一個生命周期則由ActivityLifecycleItem
的子類來表述。在一個操作完成之后(比如上面的pause操作)刺啦,可能會通知AMS進行下一步操作留特。然后客戶端繼續(xù)進行主線程的消息循環(huán),等待AMS的下一次通知。