How does the system let the desktop execute the corresponding onStart method?
The specific stack is shown below:
makeActiveIfNeeded:5788, ActivityRecord (com.android.server.wm)
makeVisibleIfNeeded:5697, ActivityRecord (com.android.server.wm)
setActivityVisibilityState:210, EnsureActivitiesVisibleHelper (com.android.server.wm)
process:143, EnsureActivitiesVisibleHelper (com.android.server.wm)
updateActivityVisibilities:1117, TaskFragment (com.android.server.wm)
lambda$ensureActivitiesVisible$18:4857, Task (com.android.server.wm)
accept:-1, Task$$ExternalSyntheticLambda23 (com.android.server.wm)
forAllLeafTasks:3174, Task (com.android.server.wm)
forAllLeafTasks:3162, Task (com.android.server.wm)
ensureActivitiesVisible:4856, Task (com.android.server.wm)
lambda$ensureActivitiesVisible$45:6293, DisplayContent (com.android.server.wm)
accept:-1, DisplayContent$$ExternalSyntheticLambda38 (com.android.server.wm)
forAllRootTasks:3186, Task (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2014, WindowContainer (com.android.server.wm)
forAllRootTasks:2007, WindowContainer (com.android.server.wm)
ensureActivitiesVisible:6292, DisplayContent (com.android.server.wm)
ensureActivitiesVisible:1864, RootWindowContainer (com.android.server.wm)
ensureActivitiesVisible:1845, RootWindowContainer (com.android.server.wm)
startRecentsActivity:260, RecentsAnimation (com.android.server.wm)
startRecentsActivity:1729, ActivityTaskManagerService (com.android.server.wm)
onTransact:1171, IActivityTaskManager$Stub (android.app)
onTransact:5183, ActivityTaskManagerService (com.android.server.wm)
execTransactInternal:1280, Binder (android.os)
execTransact:1244, Binder (android.os)
The key to the onStart call is that the startRecentsActivity here will trigger the ensureActivitiesVisible method. The normal ensureActivitiesVisible is only to ensure that some current property values of ActivityRecord or config have changed. It relies on calling ensureActivitiesVisible to ensure that the visibility of the Activity can be displayed normally.
Here
targetActivity.mLaunchTaskBehind = true;
is the most critical point, which means that it can be displayed behind other activities.
The question is why it is only onStart but not onResume:
Look at this core method makeActiveIfNeeded according to the above stack
boolean makeActiveIfNeeded(ActivityRecord activeActivity) {
//判断Activity是应该被Resume
if (shouldResumeActivity(activeActivity)) {
return getRootTask().resumeTopActivityUncheckedLocked(activeActivity /* prev */,
null /* options */);
} else if (shouldPauseActivity(activeActivity)) {
//判断Activity是应该被Pasue
setState(PAUSING, "makeActiveIfNeeded");
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
PauseActivityItem.obtain(finishing, false /* userLeaving */,
configChangeFlags, false /* dontReport */));
} else if (shouldStartActivity()) {
setState(STARTED, "makeActiveIfNeeded");
try {
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
StartActivityItem.obtain(takeOptions()));
}
mTaskSupervisor.mStoppingActivities.remove(this);
}
return false;
}
Well, the main concern here is why the shouldResumeActivity(activeActivity) method does not return true, but returns false, which leads to the shouldStartActivity method. Take a look at the shouldResumeActivity method
:
@VisibleForTesting
boolean shouldResumeActivity(ActivityRecord activeActivity) {
//主要调用到了shouldBeResumed
return shouldBeResumed(activeActivity) && !isState(RESUMED);
}
private boolean shouldBeResumed(ActivityRecord activeActivity) {
//shouldBeResumed方法又有若干条件,任何条件不满足都是不可以的,先看看第一个条件shouldMakeActive
return shouldMakeActive(activeActivity) && isFocusable()
&& getTaskFragment().getVisibility(activeActivity)
== TASK_FRAGMENT_VISIBILITY_VISIBLE
&& canResumeByCompat();
}
boolean shouldMakeActive(ActivityRecord activeActivity) {
if (!isState(STARTED, RESUMED, PAUSED, STOPPED, STOPPING)
// TODO (b/185876784) Check could we remove the check condition
// mTranslucentActivityWaiting != null here
|| getRootTask().mTranslucentActivityWaiting != null) {
return false;
}
if (this == activeActivity) {
return false;
}
if (!mTaskSupervisor.readyToResume()) {
// Making active is currently deferred (e.g. because an activity launch is in progress).
return false;
}
//核心就是这个地方,前面设置了mLaunchTaskBehind为true,所以这里就返回false了
if (this.mLaunchTaskBehind) {
// This activity is being launched from behind, which means that it's not intended to be
// presented to user right now, even if it's set to be visible.
return false;
}
return getTaskFragment().topRunningActivity() == this;
}