「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」。
今天是2022年2月15日,农历元宵节,祝各位程序员兄弟姐妹们,元宵节快乐,往后的日子红红火火,热热闹闹!!!
Launcher应用启动流程分析
前述
本篇接上篇Launcher应用启动流程分析(上)流程分析,上篇说到系统启动完成后,
- 会调用SystemServer类的startOtherServices函数,而在这个函数中会调用ActivityManagerService的systemReady函数,表明系统启动已经完成
- AMS.systemReady函数中调用ATMS服务的startHomeOnAllDisplays函数,从而最终会调用RootWindowContainner的startHomeOnTaskDisplayArea函数(针对于所有的显示设备,当然在此我们仅分析只有一个默认显示设备的情况),然后针对于这个显示设备的显示区域,会调用RootWindowContainer对象的startHomeOnTaskDisplayArea函数
- 在RootWindowContainer对象的startHomeOnTaskDisplayArea函数中,获取对应的action=Intent.ACTION_MAIN,category=Intent.CATEGORY_HOME的对应Intent对象的应用Activity对象,并最终传递给ActivityStartController对象的startHomeActivity函数
- 在ActivityStartController对象的startHomeActivity函数中,初始化一个ActivityStarter对象,并运行其execute函数 接下来,我们就从这边开始继续分析Launcher应用的启动流程
正文
确认在ActivityStartController对象的startHomeActivity函数代码
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
TaskDisplayArea taskDisplayArea) {
// 设置Home Activity的一些参数,这个Activity根据前述可知,其对应的Intent对象的
// action=Intent.ACTION_MAIN,
// category=Intent.CATEGORY_HOME
// 根据我们的经验这个对应的是Launcher3应用的Launcher对象
// 当然,从日志打印中可以看到,若安卓设备有设定Lock锁的情况下,
// 此处会启动com.android.settings.FallbackHome对象,在这个对象类中,
// 当用户通过手动或者其他方式解锁之后才会调用Launcher对象,在此处,我们不考虑这种情况
final ActivityOptions options = ActivityOptions.makeBasic();
// 设置Activity全屏
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (!ActivityRecord.isResolverActivity(aInfo.name)) {
// The resolver activity shouldn't be put in home stack because when the foreground is
// standard type activity, the resolver activity should be put on the top of current
// foreground instead of bring home stack to front.
options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
}
// 设置Activity需要显示在的显示设备和显示设备的显示区域
final int displayId = taskDisplayArea.getDisplayId();
options.setLaunchDisplayId(displayId);
options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken
.toWindowContainerToken());
// The home activity will be started later, defer resuming to avoid unneccerary operations
// (e.g. start home recursively) when creating home stack.
mSupervisor.beginDeferResume();
final ActivityStack homeStack;
try {
// Make sure home stack exists on display area.
// 创建一个ActivityStack堆栈,用作后续存放调用Activity堆栈
homeStack = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
} finally {
mSupervisor.endDeferResume();
}
// 此处初始化一个ActivityStarter对象,并运行其execute函数
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];
// 由于这个homeStack是刚刚初始化的,因此,此处mInResumeTopActivity为默认值false
if (homeStack.mInResumeTopActivity) {
// If we are in resume section already, home activity will be initialized, but not
// resumed (to avoid recursive resume) and will stay that way until something pokes it
// again. We need to schedule another resume.
mSupervisor.scheduleResumeTopActivities();
}
}
由上述的代码和备注可以看到,此处最终只会调用obtainStarter函数初始化一个ActivityStarter对象,最终调用其execute函数来初始化对应的Activity对象
int execute() {
try {
// ...... 判空操作代码省略
int res;
synchronized (mService.mGlobalLock) {
// ...... 日志代码省略
// 调用executeRequest函数
res = executeRequest(mRequest);
// ...... 功能无关代码省略
// 获取最终的结果
return getExternalResult(mRequest.waitResult == null ? res
: waitForResult(res, mLastStartActivityRecord));
}
} finally {
// 当上述代码运行结束后,调用此函数onExecutionComplete,用作设置最终运行状态
onExecutionComplete();
}
}
如上代码可知,主要会做三个操作
- 调用executeRequest函数,运行Activity
- 调用getExternalResult函数,获取最终运行的结果
- 调用onExecutionComplete函数,主要用作运行结束后设置部分对象状态 此处,我们主要分析第一条,确认Launcher应用的启动过程
private int executeRequest(Request request) {
// ...... 判空和初始化操作,此处省略
// 初始化一个ActivityRecord对象
final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, callingFeatureId, intent, resolvedType, aInfo,
mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
sourceRecord);
// 这边将本次启动的ActivityRecord对象赋值到Last ActivityRecord中保存
mLastStartActivityRecord = r;
if (r.appTimeTracker == null && sourceRecord != null) {
// If the caller didn't specify an explicit time tracker, we want to continue
// tracking under any it has.
r.appTimeTracker = sourceRecord.appTimeTracker;
}
// 还记得,在此前startHomeActivity函数中通过TaskDisplayArea初始化的一个ActivityStack么?
// 此处会获取该对象
final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
// ...... 功能无关代码,此处省略
// 设置ATMS的mDidAppSwitch参数为true
mService.onStartActivitySetDidAppSwitch();
// 控制已经等待Activity的启动,此处为空,自然直接跳出
mController.doPendingActivityLaunches(false);
// 最终调用此处的startActivityUnchecked函数
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
if (request.outActivity != null) {
// 设置request的返回ActivityRecord对象
request.outActivity[0] = mLastStartActivityRecord;
}
return mLastStartActivityResult;
}
可以看到,此处启动Activity对象主要会调用startActivityUnchecked函数
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
int result = START_CANCELED;
final ActivityStack startedActivityStack;
try {
mService.deferWindowLayout();
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
// 调用startActivityInner函数
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
// 返回调用堆栈
startedActivityStack = handleStartResult(r, result);
mService.continueWindowLayout();
}
// ...... 功能无关代码省略
return result;
}
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
// 设置ActivityStarter初始化状态
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
// 获取本次Activity启动的flags
computeLaunchingTaskFlags();
computeSourceStack();
// 设置对应的启动flags
mIntent.setFlags(mLaunchFlags);
// 从代码和打印日志中可以分析,此处会返回一个null
final Task reusedTask = getReusableTask();
// ......
// Compute if there is an existing task that should be used for.
// 返回null
final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
final boolean newTask = targetTask == null;
mTargetTask = targetTask;
// 获取对应参数
computeLaunchParams(r, sourceRecord, targetTask);
// ......
// 返回null,有兴趣可以自行分析
final ActivityRecord targetTaskTop = newTask
? null : targetTask.getTopNonFinishingActivity();
if (targetTaskTop != null) {
// ......
} else {
mAddingToTask = true;
}
// If the activity being launched is the same as the one currently at the top, then
// we need to check if it should only be launched once.
// 获取此前创建的ActivityStack
final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
if (topStack != null) {
startResult = deliverToCurrentTopIfNeeded(topStack, intentGrants);
if (startResult != START_SUCCESS) {
return startResult;
}
}
if (mTargetStack == null) {
// 获取TargetStack,这边主要是新建一个ActivityStack,然后将其添加到对应的TaskDisplayArea中
mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
// ......
mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(
false /* forceSend */, mStartActivity);
// 通过ActivityStack的startActivityLocked函数调用,将对应的ActivityRecord添加到对应的ActivityStack
mTargetStack.startActivityLocked(mStartActivity,
topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
mKeepCurTransition, mOptions);
// true
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
// ....... if语句无法进入,代码省略
} else {
// If the target stack was not previously focusable (previous top running activity
// on that stack was not visible) then any prior calls to move the stack to the
// will not update the focused stack. If starting the new activity now allows the
// task stack to be focusable, then ensure that we now update the focused stack
// accordingly.
if (mTargetStack.isTopActivityFocusable()
&& !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityInner");
}
// 通过获取ActivityStack对象mTargetStack中的ActivityRecord对象
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
}
mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);
// 更新Recents Tasks
// Update the recent tasks list immediately when the activity starts
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetStack);
return START_SUCCESS;
}
从上述代码中可以看到,这边主要是做了
- 通过ActivityStack的startActivityLocked函数调用,将对应的ActivityRecord添加到对应的ActivityStack,这边可以分析下代码,主要同时
- 此后通过RootWindowContainer的resumeFocusedStacksTopActivities函数,从ActivityStack中获取对应的Activity并启动
总结
从本篇中分析的代码可知,在Launcher应用的启动过程中,会
- 初始化一个包含启动Activity信息的ActivityRecord对象
- 初始化一个ActivityStack,用作存放启动Activity的堆栈
- 然后将上述的保存Activity信息的ActivityRecord对象存放到ActivityStack堆栈
- 通过RootWindowContainner对象的resumeFocusedStacksTopActivities函数启动对应的Activity