生命周期相关
这里还是以多任务中启动自由窗口为例
//进入多任务
01-20 10:36:00.892 1399 1399 I wm_on_restart_called: [77094127,com.android.launcher3.uioverrides.QuickstepLauncher,performRestart,0]
01-20 10:36:00.917 1399 1399 I wm_on_start_called: [77094127,com.android.launcher3.uioverrides.QuickstepLauncher,handleStartActivity,25]
01-20 10:36:00.920 1399 1399 I wm_on_resume_called: [77094127,com.android.launcher3.uioverrides.QuickstepLauncher,RESUME_ACTIVITY,0]
01-20 10:36:01.011 1399 1399 I wm_on_top_resumed_gained_called: [77094127,com.android.launcher3.uioverrides.QuickstepLauncher,topStateChangedWhenResumed]
//启动自由窗口
01-20 10:36:26.706 1399 1399 I wm_on_top_resumed_lost_called: [77094127,com.android.launcher3.uioverrides.QuickstepLauncher,topStateChangedWhenResumed]
01-20 10:36:26.736 2378 2378 I wm_on_stop_called: [180634051,com.android.messaging.ui.conversationlist.ConversationListActivity,handleRelaunchActivity,0]
01-20 10:36:26.756 2378 2378 I wm_on_destroy_called: [180634051,com.android.messaging.ui.conversationlist.ConversationListActivity,performDestroy,10]
01-20 10:36:26.930 2378 2378 I wm_on_create_called: [180634051,com.android.messaging.ui.conversationlist.ConversationListActivity,performCreate,64]
01-20 10:36:26.938 2378 2378 I wm_on_start_called: [180634051,com.android.messaging.ui.conversationlist.ConversationListActivity,handleStartActivity,0]
01-20 10:36:27.006 2378 2378 I wm_on_resume_called: [180634051,com.android.messaging.ui.conversationlist.ConversationListActivity,RESUME_ACTIVITY,53]
01-20 10:36:27.072 2378 2378 I wm_on_top_resumed_gained_called: [180634051,com.android.messaging.ui.conversationlist.ConversationListActivity,topStateChangedWhenResumed]
发现 启动自由窗口时底层activity(launcher3)不会进行pause。 一般来说当一个应用resume,那么当前应用就会走pause流程,我们这里launcher3为什么没有走pause呢?我们简单跟踪一下流程。 代码路径:frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
......
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
先看这个resume流程,这会去判断是否需要pause。
这里deferPause的值是通过Task.resumeTopActivityUncheckedLocked方法中传递过来的,其值为false,因此!deferPause为true。
next指的是要启动的activity(我们这里是ConversationListActivity)。
代码路径:frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
/**
* Pause all activities in either all of the root tasks or just the back root tasks. This is
* done before resuming a new activity and to make sure that previously active activities are
* paused in root tasks that are no longer visible or in pinned windowing mode. This does not
* pause activities in visible root tasks, so if an activity is launched within the same root
* task, hen we should explicitly pause that root task's top activity.
*
* @param resuming The resuming activity.
* @return {@code true} if any activity was paused as a result of this call.
*/
boolean pauseBackTasks(ActivityRecord resuming) {
final int[] someActivityPaused = {0};
forAllLeafTasks(leafTask -> {
// Check if the direct child resumed activity in the leaf task needed to be paused if
// the leaf task is not a leaf task fragment.
//task fragment场景,暂不关注
if (!leafTask.isLeafTaskFragment()) {
final ActivityRecord top = topRunningActivity();
final ActivityRecord resumedActivity = leafTask.getResumedActivity();
if (resumedActivity != null && top.getTaskFragment() != leafTask) {
// Pausing the resumed activity because it is occluded by other task fragment.
if (leafTask.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
someActivityPaused[0]++;
}
}
}
//遍历所有leafTask节点,即最底端Task节点
leafTask.forAllLeafTaskFragments((taskFrag) -> {
final ActivityRecord resumedActivity = taskFrag.getResumedActivity();
//判断当前taskFrag是否有存在resumed的Activity,并且即将启动的Activity不能resumed
if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) {
//暂停当前存在resumed的Activity
if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
//记录暂停的Activity
someActivityPaused[0]++;
}
}
}, true /* traverseTopToBottom */);
}, true /* traverseTopToBottom */);
return someActivityPaused[0] > 0;
}
这个方法会遍历TaskDisplayArea下的所有leafTask节点,即最底端Task节点
- 判断当前Task的Activity是否存在resumed状态,且即将启动的Activity不能被resumed
- 暂停当前存在resumed的Activity,若暂停成功,给参数
someActivityPaused计数
如下图圈的task节点是会遍历的task节点。
在该界面当我们点击启动自由窗口后开始条件判断
resumedActivity != null && !taskFrag.canBeResumed(resuming)。
taskFrag.getResumedActivity()获取此时是resumed状态的task,当遍历到桌面Task时,由于我们要从多任务进入到自由窗口,而此时多任务界面为resumed状态,存在resumed状态的Activity,因此参数resumedActivity不为空。
这里resumedActivity != null为true,再来看看!taskFrag.canBeResumed(resuming)其中参数resuming指的是即将启动的Activity(ConversationListActivity)。
代码路径:frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
/**
* Returns {@code true} is the activity in this TaskFragment can be resumed.
*
* @param starting The currently starting activity or {@code null} if there is none.
*/
boolean canBeResumed(@Nullable ActivityRecord starting) {
// No need to resume activity in TaskFragment that is not visible.
return isTopActivityFocusable()
&& getVisibility(starting) == TASK_FRAGMENT_VISIBILITY_VISIBLE;
}
isTopActivityFocusable()判断顶部Activity是否可聚焦,一般为true,这里主要关注getVisibility(starting)方法,通样传递starting即将启动的的Activity (ConversationListActivity)。
/**
* Returns the visibility state of this TaskFragment.
*
* @param starting The currently starting activity or null if there is none.
*/
@TaskFragmentVisibility
int getVisibility(ActivityRecord starting) {
......
//根据上述代码流程,这里this指的是桌面task,因此此时getParent获取的是桌面task的task
final WindowContainer<?> parent = getParent();
......
// This TaskFragment is only considered visible if all its parent TaskFragments are
// considered visible, so check the visibility of all ancestor TaskFragment first.
//判断parent是否是task或者TaskFragment
if (parent.asTaskFragment() != null) {
//递归调用getVisibility,直到parent为TaskDisplayArea(不是task)为止。
//其目的是为了能够遍历到TaskDisplayArea下所有task节点
final int parentVisibility = parent.asTaskFragment().getVisibility(starting);
if (parentVisibility == TASK_FRAGMENT_VISIBILITY_INVISIBLE) {
// Can't be visible if parent isn't visible
return TASK_FRAGMENT_VISIBILITY_INVISIBLE;
} else if (parentVisibility == TASK_FRAGMENT_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT) {
// Parent is behind a translucent container so the highest visibility this container
// can get is that.
gotTranslucentFullscreen = true;
}
}
final List<TaskFragment> adjacentTaskFragments = new ArrayList<>();
//逆序遍历parent下的task,即优先最前台,从大到小遍历
for (int i = parent.getChildCount() - 1; i >= 0; --i) {
final WindowContainer other = parent.getChildAt(i);
if (other == null) continue;
//判断other是否是运行中的Activity
final boolean hasRunningActivities = hasRunningActivity(other);
//other和this相同则中断循环,做后续处理
if (other == this) {
......
// Should be visible if there is no other fragment occluding it, unless it doesn't
// have any running activities, not starting one and not home stack.
shouldBeVisible = hasRunningActivities
|| (starting != null && starting.isDescendantOf(this))
|| isActivityTypeHome();
break;
}
if (!hasRunningActivities) {
continue;
}
//根据other的WindowingMode判断返回值
final int otherWindowingMode = other.getWindowingMode();
if (otherWindowingMode == WINDOWING_MODE_FULLSCREEN) {
if (isTranslucent(other, starting)) {
// Can be visible behind a translucent fullscreen TaskFragment.
gotTranslucentFullscreen = true;
continue;
}
return TASK_FRAGMENT_VISIBILITY_INVISIBLE;
} else if (otherWindowingMode == WINDOWING_MODE_MULTI_WINDOW
&& other.matchParentBounds()) {
if (isTranslucent(other, starting)) {
// Can be visible behind a translucent TaskFragment.
gotTranslucentFullscreen = true;
continue;
}
// Multi-window TaskFragment that matches parent bounds would occlude other children
return TASK_FRAGMENT_VISIBILITY_INVISIBLE;
}
......
}
if (!shouldBeVisible) {
return TASK_FRAGMENT_VISIBILITY_INVISIBLE;
}
// Lastly - check if there is a translucent fullscreen TaskFragment on top.
return gotTranslucentFullscreen
? TASK_FRAGMENT_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT
: TASK_FRAGMENT_VISIBILITY_VISIBLE;
}
简单来说这个方法就是判断当前启动之后的activity的WindowingMode如果不是WINDOWING_MODE_FULLSCREEN或者WINDOWING_MODE_MULTI_WINDOW那么就返回TASK_FRAGMENT_VISIBILITY_VISIBLE,使后台应用可见,不进入到pause流程。
因此启动自由窗口时底层activity(launcher3)不会进行pause。