携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
上一篇文章 App启动流程【2】Activity 到 ActivityTaskManagerService 的调用流程 的最后来到了 ActivityTaskManagerService 中的 startActivity 方法中,继续向下分析。
ActivityTaskManagerService.startActivity
ActivityTaskManagerService 的 startActivity 方法:
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
startActivity 中转到 startActivityAsUser
@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
真实逻辑在私有的 startActivityAsUser 方法中:
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
}
这个方法中最核心的逻辑是通过 ActivityStartController 执行 execute 方法并返回一个 int 值。
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
mActivityStartController 的初始化在:
public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController, Looper looper) {
// ...
mActivityStartController = new ActivityStartController(this);
}
obtainStarter 方法返回的是一个 ActivityStarter 对象:
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
ActivityStarter
ActivityStarter 是用于阐述如何启动 Activity 的 Controller 。此类包含了所有用于确定如何将 intent 和 flag 转换为 Activity 和它关联的任务栈信息的逻辑。
ActivityStarter 配置了一些信息后,执行 execute 方法,execute 方法的注释描述了这个方法的作用:
根据前面提供的请求参数解析必要的信息,并执行请求,开始 start 一个 Activity 的旅程。
int execute() {
try {
// 1. 拒绝可能泄露的文件描述符
// 2. 更新 LaunchingState
// 3. 如果调用者尚未 resolveActivity ,我们会在这里这样做。
// 4. 为此关闭或重新启动尝试添加检查点,以便我们可以记录原始 intent 操作和包名称。
int res;
synchronized (mService.mGlobalLock) {
// ...
// Task 是一个 TaskFragment,可以包含一组 Activity 来执行特定的工作。
// 相同 Task 关联的 Activity 通常分组在同一个 Task 中。 Task 也可以是在最近屏幕中显示的与用户交互的作业的实体。
// Task 还可以包含其他 Task。
final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (rootTask != null) {
rootTask.mConfigWillChange = globalConfigWillChange;
}
final long origId = Binder.clearCallingIdentity();
// 如果这是一个重量级进程而已经有另一个不同的重量级进程在运行,则将请求日期到重量级切换。
res = resolveToHeavyWeightSwitcherIfNeeded();
if (res != START_SUCCESS) {
return res;
}
// * 执行请求
res = executeRequest(mRequest);
Binder.restoreCallingIdentity(origId);
// 更新配置
// 通知 ActivityMetricsLogger ,Activity 已启动。然后 ActivityMetricsLogger 将等待 window 被绘制并填充 WaitResult。
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
newActivityCreated, mLastStartActivityRecord, originalOptions);
if (mRequest.waitResult != null) {
mRequest.waitResult.result = res;
res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
launchingState);
}
return getExternalResult(res);
}
} finally {
onExecutionComplete();
}
}
在核心逻辑执行前,会做一些准备工作:
- 拒绝可能泄露的文件描述符
- 更新 LaunchingState
- 确保执行 resolveActivity
- 添加 checkpoint ,记录原始的 intent 和包名。
然后是需要同步执行的核心部分:
- 更新即将更新 flag
- resolveToHeavyWeightSwitcherIfNeeded
- executeRequest
- Binder.restoreCallingIdentity(origId)
- 更新配置
- 通知 ActivityMetricsLogger Activity 已启动,等待 window 绘制并填充,返回 WaitResult 。
- 返回 getExternalResult
这里比较核心的是 executeRequest
执行 Activity 启动请求并开始启动 Activity 的旅程。这里首先执行几个初步检查。
正常的 Activity 启动流程将通过 startActivityUnchecked 到 startActivityInner 。
过滤出关键逻辑:
private int executeRequest(Request request) {
// ...
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
mLastStartActivityRecord = r;
// ...
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask, inTaskFragment, restrictedBgActivity, intentGrants);
if (request.outActivity != null) {
request.outActivity[0] = mLastStartActivityRecord;
}
return mLastStartActivityResult;
}
在这个方法中,重点的两个逻辑是:
- 构造 ActivityRecord 对象,记录上一次最后启动记录
- 通过 startActivityUnchecked 继续启动 Activity
前者无需多言,继续跟进后者:
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
// ...
try {
mService.deferWindowLayout();
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
intentGrants);
} finally {
startedActivityRootTask = handleStartResult(r, options, result, newTransition,
remoteTransition);
mService.continueWindowLayout();
}
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
}
startActivityUnchecked 调用到了 startActivityInner :
启动一个 Activity 并决定如果 Activity 是否应该添加到已存在的 Task 顶部,还是发送一个新的 Intent 到一个已存在的 Activity 。
注意:这个方法应该只能从 startActivityUnchecked 调用
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
// ...
// 获取 Target Root Task
if (mTargetRootTask == null) {
mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
// ...
final boolean isTaskSwitch = startedTask != prevTopTask && !startedTask.isEmbedded();
mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch, mOptions, sourceRecord);
if (mDoResume) {
final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
if (!mTargetRootTask.isTopActivityFocusable() || (topTaskActivity != null && topTaskActivity.isTaskOverlay() && mStartActivity != topTaskActivity)) {
mTargetRootTask.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS);
mTargetRootTask.mDisplayContent.executeAppTransition();
} else {
if (mTargetRootTask.isTopActivityFocusable() && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
mTargetRootTask.moveToFront("startActivityInner");
}
// Activity 进入 resume
mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
}
mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
// Activity 启动后更新最近任务列表
mSupervisor.mRecentTasks.add(startedTask);
mSupervisor.handleNonResizableTaskIfNeeded(startedTask, mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
// ...
return START_SUCCESS;
}
在这个方法中,处理了 Activity 所依附的 Task 的相关逻辑,这里很复杂有兴趣可以自行查看这个方法的源码。本文只关注重点逻辑。
经过一系列的 Task 检查和构造后,通过 mTargetRootTask.startActivityLocked 方法继续进行核心的启动 Activity 逻辑。
在 Activity 启动后,通过 mRootWindowContainer.resumeFocusedTasksTopActivities(...) 使 Activity 获取焦点,然后更新 Task 栈,做完这些工作,最后的一个步骤是更新最近任务列表。
到这一步,启动 Activity 的核心逻辑就落到了 Task 类中。