本文基于 android-14.0.0_r15 版本讲解
# 1.回顾
上一节,我们分析了,Activity 启动请求到达 SystemServer 端后,SystemServer 端主要要完成以下一些工作:
- 解析与处理请求参数,要启动那个 Activity,怎么启动(flags 等参数),是谁启动等等一些信息
- 修改窗口容器树,创建新的 ActivityRecord 与 Task 并挂载到窗口容器树中
- pause 源 Activity
- 启动新进程,触发 Application Activity 的初始化和启动生命周期回调
前面的章节已经分析了前两点,本节接着分析第三点。
# 2. 概述
如果你做过 App 的开发,应该非常熟悉 Acitivyt A 启动 Activty B 的生命周期调度情况:
Activity A Activity B
onCreate
onStart
onResume
onPause -- 待分析的阶段
onCreate
onStart
onResume
onStop
2
3
4
5
6
7
8
9
10
接下来我们就来分析 Activity A onPause 的过程。
上一节说到 Activity 启动过程中,会调用到 resumeFocusedTasksTopActivities
方法,该方法会 pause 前一个 Activity,接下来我们就来分析一下这部分源码。
SystemServer 端的调用链如下:
RootWindowContainer::resumeFocusedTasksTopActivities
Task::resumeTopActivityUncheckedLocked -- Task 就是新创建的目标 Task
Task::resumeTopActivityInnerLocked
TaskFragment::resumeTopActivity -- TaskFragment 是 Task 的父节点
taskDisplayArea.pauseBackTasks -- DefaultTaskDisplayArea
Task::startPausing -- Launcher 所在的 Task
TaskFragment::schedulePauseActivity -- 调用到父类 TaskFragment 中的方法
PauseActivityItem::obtain -- 构建一个 PauseActivityItem 对象
ClientLifecycleManager::scheduleTransaction
transactionWithState -- 构建一个 ClientTransaction 对象
scheduleTransaction
ClientTransaction::schedule
IApplicationThread::scheduleTransaction -- 远程调用到 app 端
2
3
4
5
6
7
8
9
10
11
12
13
14
App 端的调用链如下:
sendMessage
handleMessage
mTransactionExecutor.execute(transaction)
executeCallbacks(transaction) -- 执行回调
executeLifecycleState -- 执行生命周期
lifecycleItem.execute
ClientTransactionHandler::handlePauseActivity
performPauseActivity
performPauseActivityIfNeeded
Instrumentation::callActivityOnPause
Activity::performPause
Activity::onPause
lifecycleItem.postExecute
ActivityClient::activityPaused
2
3
4
5
6
7
8
9
10
11
12
13
14
# 2. 准备阶段
准备阶段主要是做一些特殊情况的判断,确定一些参数值。
resumeFocusedTasksTopActivities 方法的具体实现如下:
// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
class RootWindowContainer extends WindowContainer<DisplayContent>
implements DisplayManager.DisplayListener {
//......
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
// ......
boolean result = false;
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) { // 进入
// 关注点
// targetRootTask 就是刚创建的目标 Task
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
}
// ......
return result;
}
//......
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
从方法的名字 resumeFocusedTasksTopActivities
可以看出,这里是要 resume FocusedTasks 中的 TopActivities。
这里我们主要关注 resumeTopActivityUncheckedLocked 方法,名字可以看出是找到了 FocusedTasks,现在要 resume TopActivity:
// frameworks/base/services/core/java/com/android/server/wm/Task.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (mInResumeTopActivity) { // 不进入
// Don't even start recursing.
return false;
}
boolean someActivityResumed = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
if (isLeafTask()) { //叶子 Task 节点
if (isFocusableAndVisible()) { // 有焦点且可见。 进入
someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
}
} else {
// ......
}
final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return someActivityResumed;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
判断当前 Task 是叶子 Task 节点,所谓叶子 Task 节点,就是该节点的子节点中没有 Task 类型的节点
接着判断当前节点是有焦点且可见。
当前节点满足这两个条件,接着调用 resumeTopActivityInnerLocked:
// frameworks/base/services/core/java/com/android/server/wm/Task.java
/*
pre:名字有点迷惑性,实际是目标 ActivityRecord
*/
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (!mAtmService.isBooting() && !mAtmService.isBooted()) { // 不进入
// Not ready yet!
return false;
}
// topRunningActivity 返回的是目标 ActivityRecord,
// 和 pre 是同一个对象
final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
if (topActivity == null) { // 不进入
// There are no activities left in this task, let's look somewhere else.
return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
}
final boolean[] resumed = new boolean[1];
final TaskFragment topFragment = topActivity.getTaskFragment(); //topFragment,目标 Task 的父节点 DefaultTaskFragment
// 关注点
resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
// 子节点处理,当前情景下应该是没有子节点的
forAllLeafTaskFragments(f -> {
if (topFragment == f) {
return;
}
if (!f.canBeResumed(null /* starting */)) {
return;
}
resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
}, true);
return resumed[0];
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
这里的 pre topActivity 都是目标 ActivityRecord。
这里通过 topActivity.getTaskFragment 获取到目标 Task,接着调用目标 Task 对象的 resumeTopActivity 方法:
// frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
// 目标 Activity
ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canResumeByCompat()) {
return false;
}
next.delayedResume = false;
// If we are currently pausing an activity, then don't do anything until that is done.
final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete(); // true
if (!allPausedComplete) { // 不进入
ProtoLog.v(WM_DEBUG_STATES,
"resumeTopActivity: Skip resume: some activity pausing.");
return false;
}
// DefaultTaskDisplayArea
final TaskDisplayArea taskDisplayArea = getDisplayArea();
// If the top activity is the resumed one, nothing to do.
if (mResumedActivity == next && next.isState(RESUMED)
&& taskDisplayArea.allResumedActivitiesComplete()) { // 不进入
// ......
}
// ......
// The activity may be waiting for stop, but that is no longer
// appropriate for it.
mTaskSupervisor.mStoppingActivities.remove(next);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
mTaskSupervisor.setLaunchSource(next.info.applicationInfo.uid);
ActivityRecord lastResumed = null;
// 目标 task
final Task lastFocusedRootTask = taskDisplayArea.getLastFocusedRootTask();
if (lastFocusedRootTask != null && lastFocusedRootTask != getRootTaskFragment().asTask()) { // 进入
// So, why aren't we using prev here??? See the param comment on the method. prev
// doesn't represent the last resumed activity. However, the last focus stack does if
// it isn't null.
lastResumed = lastFocusedRootTask.getTopResumedActivity(); // QuickstepLauncher
}
// 重点关注
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
// ......
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
调用 Task 的 getDisplayArea 方法获取到 Task 的 TaskDisplayArea 类型父节点。也就是 DefualtTaskDisplayArea
接着调用 taskDisplayArea.pauseBackTasks 方法:
# 3. 发起 Pause 远程调用
// frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
// resuming 就是目标 ActivityRecord
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.
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.forAllLeafTaskFragments((taskFrag) -> {
final ActivityRecord resumedActivity = taskFrag.getResumedActivity();
if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) {
// taskFrag 就是 QuickstepLauncher
if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) { //会走到这
someActivityPaused[0]++;
}
}
}, true /* traverseTopToBottom */);
}, true /* traverseTopToBottom */);
return someActivityPaused[0] > 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
这里会对窗口树结构进行局部条件遍历,找到符合要求的 Task 节点后,这里要求主要是指栈顶的 ActivityRecord 是 resumed 状态的,当前场景就是 launcher 。接着调用 Task startPausing 方法,向 App 发起 Binder RPC 调用,pause Activity。
# 3.1 窗口树的局部条件遍历
所谓树的局部条件遍历,就是遍历每一个节点,取出符合条件的节点,传入回调方法。
具体我们看代码:
TaskDisplayArea 对象的 forAllLeafTasks 方法定义在父类 WindowContainer 中:
// frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
void forAllLeafTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
final int count = mChildren.size();
if (traverseTopToBottom) { // traverseTopToBottom 值为 true,走这个分支
for (int i = count - 1; i >= 0; --i) {
mChildren.get(i).forAllLeafTasks(callback, traverseTopToBottom);
}
} else {
for (int i = 0; i < count; i++) {
mChildren.get(i).forAllLeafTasks(callback, traverseTopToBottom);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
遍历 TaskDisplayArea 的所有子节点,然后调用子节点的 forAllLeafTasks 方法。
当前情景下 TaskDisplayArea 的子节点情况如下:
三个子节点的类型均为 Task,接着就会调用到 Task 的 forAllLeafTasks 方法:
// frameworks/base/services/core/java/com/android/server/wm/Task.java
void forAllLeafTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
final int count = mChildren.size();
boolean isLeafTask = true;
if (traverseTopToBottom) {
for (int i = count - 1; i >= 0; --i) {
final Task child = mChildren.get(i).asTask();
if (child != null) {
isLeafTask = false;
child.forAllLeafTasks(callback, traverseTopToBottom);
}
}
} else {
for (int i = 0; i < count; i++) {
final Task child = mChildren.get(i).asTask();
if (child != null) {
isLeafTask = false;
child.forAllLeafTasks(callback, traverseTopToBottom);
}
}
}
if (isLeafTask) callback.accept(this);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Task 的字节点可以是 Task,也可以是 ActivityRecord。
Task 中定义有 asTask() 方法:
// frameworks/base/services/core/java/com/android/server/wm/Task.java
@Override
Task asTask() {
// I'm a task!
return this;
}
2
3
4
5
6
ActivityRecord 中 asTask() 方法实现在其父类 WindowContainor 中:
// frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
Task asTask() {
return null;
}
2
3
4
回到 Task 的 forAllLeafTasks 方法中,这里会对 Task 的子节点进行遍历:
- 如果子节点是 Task 类型,asTask 方法返回的不是空,继续调用子节点的 forAllLeafTasks 方法
- 如果子节点是 ActivityRcord 类型,asTask 方法返回空,isLeafTask 的值会是 true,就会调用传入的回调方法
callback.accept(this)
,并将当前 Task 作为参数传入
对于 forAllLeafTasks 方法,我们简单总结一下:
- 找到 Task 类型的子节点
- 如果该节点的子节点中有 ActivityRecord,调用传入的回调方法
callback.accept
,并传入 Task 对象
接下来我们来看看回调方法的实现,回调方法是一个拉姆达表达式:
// 主要关注回调
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.
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.forAllLeafTaskFragments((taskFrag) -> {
final ActivityRecord resumedActivity = taskFrag.getResumedActivity();
if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) {
// taskFrag 就是 QuickstepLauncher
if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) { //会走到这
someActivityPaused[0]++;
}
}
}, true /* traverseTopToBottom */);
}, true /* traverseTopToBottom */);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
前面分析出 leafTask 的类型是 Task,回调方法中先调用 Task 的 isLeafTaskFragment 方法做一个判断:
isLeafTaskFragment 方法定义在 Task 的父类 TaskFragment 中:
// frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
boolean isLeafTaskFragment() {
for (int i = mChildren.size() - 1; i >= 0; --i) {
if (mChildren.get(i).asTaskFragment() != null) {
return false;
}
}
return true;
}
2
3
4
5
6
7
8
9
这里遍历 Task 的子节点,并调用子节点对象的 asTaskFragment 方法,Task 的子节点类型可以是 Task 和 ActivityRecord,他们的 asTaskFragment 方法均实现在父类 WindowContainer 中:
TaskFragment asTaskFragment() {
return null;
}
2
3
这里返回 null,也就是意味着 isLeafTaskFragment 永远返回 true。
也就是说回调方法中的第一个 if 是不会执行到的。
接着会调用到 Task 的 forAllLeafTaskFragments 方法:
@Override
void forAllLeafTaskFragments(Consumer<TaskFragment> callback, boolean traverseTopToBottom) {
final int count = mChildren.size();
boolean isLeafTaskFrag = true;
if (traverseTopToBottom) {
for (int i = count - 1; i >= 0; --i) {
final TaskFragment child = mChildren.get(i).asTaskFragment();
if (child != null) {
isLeafTaskFrag = false;
child.forAllLeafTaskFragments(callback, traverseTopToBottom);
}
}
} else {
for (int i = 0; i < count; i++) {
final TaskFragment child = mChildren.get(i).asTaskFragment();
if (child != null) {
isLeafTaskFrag = false;
child.forAllLeafTaskFragments(callback, traverseTopToBottom);
}
}
}
if (isLeafTaskFrag) callback.accept(this);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
执行逻辑和前面的 forAllLeafTasks 类似。
最终会执行到回调方法 callback.accept,传入的参数是当前 Task。
最终,对于每一个叶子 Task 节点会执行下面的回调:
leafTask.forAllLeafTaskFragments((taskFrag) -> {
final ActivityRecord resumedActivity = taskFrag.getResumedActivity(); // 获取到 Task 中的 resumed 状态的 ActivityRecord
if (resumedActivity != null && !taskFrag.canBeResumed(resuming))
if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) { //会走到这
someActivityPaused[0]++;
}
}
}, true /* traverseTopToBottom */);
2
3
4
5
6
7
8
# 3.2 发起远程调用,pause 前一个 Activity
接着会执行到源 Task 的 startPausing 方法.
// frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final boolean startPausing(boolean uiSleeping, ActivityRecord resuming, String reason) {
return startPausing(mTaskSupervisor.mUserLeaving, uiSleeping, resuming, reason);
}
boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
String reason) {
if (!hasDirectChildActivities()) { // 不进入
return false;
}
ProtoLog.d(WM_DEBUG_STATES, "startPausing: taskFrag =%s " + "mResumedActivity=%s", this,
mResumedActivity);
if (mPausingActivity != null) { // 不进入
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.getState());
if (!shouldSleepActivities()) {
// Avoid recursion among check for sleep and complete pause during sleeping.
// Because activity will be paused immediately after resume, just let pause
// be completed by the order of activity paused from clients.
completePause(false, resuming);
}
}
ActivityRecord prev = mResumedActivity;
if (prev == null) { // 不进入
if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed");
mRootWindowContainer.resumeFocusedTasksTopActivities();
}
return false;
}
if (prev == resuming) { // 不进入
Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
return false;
}
ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSING: %s", prev);
// Launcher 中的 Activity
mPausingActivity = prev;
mLastPausedActivity = prev;
if (!prev.finishing && prev.isNoHistory()
&& !mTaskSupervisor.mNoHistoryActivities.contains(prev)) {
mTaskSupervisor.mNoHistoryActivities.add(prev);
}
// 设置状态,实际会通过 binder 通知到 App,不是重点
prev.setState(PAUSING, "startPausingLocked");
prev.getTask().touchActiveTime();
mAtmService.updateCpuStats();
boolean pauseImmediately = false;
boolean shouldAutoPip = false;
if (resuming != null) { // 进入
// We do not want to trigger auto-PiP upon launch of a translucent activity.
final boolean resumingOccludesParent = resuming.occludesParent();
// Resuming the new resume activity only if the previous activity can't go into Pip
// since we want to give Pip activities a chance to enter Pip before resuming the
// next activity.
final boolean lastResumedCanPip = prev.checkEnterPictureInPictureState(
"shouldAutoPipWhilePausing", userLeaving);
if (userLeaving && resumingOccludesParent && lastResumedCanPip
&& prev.pictureInPictureArgs.isAutoEnterEnabled()) {
shouldAutoPip = true;
} else if (!lastResumedCanPip) {
// If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous
// activity to be paused.
pauseImmediately = (resuming.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
} else {
// The previous activity may still enter PIP even though it did not allow auto-PIP.
}
}
if (prev.attachedToProcess()) {
if (shouldAutoPip) {
prev.mPauseSchedulePendingForPip = true;
boolean didAutoPip = mAtmService.enterPictureInPictureMode(
prev, prev.pictureInPictureArgs, false /* fromClient */);
ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode "
+ "directly: %s, didAutoPip: %b", prev, didAutoPip);
} else { // 走这里
schedulePauseActivity(prev, userLeaving, pauseImmediately,
false /* autoEnteringPip */, reason);
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mTaskSupervisor.mNoHistoryActivities.remove(prev);
}
// ......
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
接着会调用到 schedulePauseActivity,在这个方法中会向源 App 发起远程调用:
// frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
boolean pauseImmediately, boolean autoEnteringPip, String reason) {
ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
try {
prev.mPauseSchedulePendingForPip = false;
EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving, reason);
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately, autoEnteringPip));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mTaskSupervisor.mNoHistoryActivities.remove(prev);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
关键步骤:
- getLifecycleManager
- PauseActivityItem.obtain:构造一个 PauseActivityItem 对象
- scheduleTransaction
接着调用 mService.getLifecycleManager().scheduleTransaction
向 App 端发起 Binder RPC 调用:
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
private final ClientLifecycleManager mLifecycleManager;
ClientLifecycleManager getLifecycleManager() {
return mLifecycleManager;
}
// /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/**
* 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);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
接着调用重载 scheduleTransaction:
// frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
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();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
接着调用 schedule:
// /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/** Target client. */
private IApplicationThread mClient;
/**
* 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);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
层层调用到 IApplicationThread 的 scheduleTransaction 方法,这是一个 Binder RPC 调用:
远程调用 App 端的 scheduleTransaction 方法,调用该方法后,App 端会 pause 前一个 Activity。
ATMS 远程调用到 App 端的 scheduleTransaction 方法:
// /frameworks/base/core/java/android/app/ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
// ......
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
// ......
}
2
3
4
5
6
7
8
9
10
接着调用到 App 端中 ActivityThread 的 scheduleTransaction 方法:
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
2
3
4
5
这里会发送一个 Message,ActivityThread 中的 Handler 中会处理到这个 Message:
// /frameworks/base/core/java/android/app/ActivityThread.java
public void handleMessage(Message msg) {
case EXECUTE_TRANSACTION:
// 从 Message 中取出消息
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();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 从 Message 中取出消息
- 执行消息
接着我们来看执行消息的过程:
// /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
// ......
// 执行回调
executeCallbacks(transaction);
// 执行生命周期
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
接着调用 executeLifecycleState
来执行生命周期:
// /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
// 从 ClientTransaction 中拿到 ActivityLifecycleItem,这里是子类 PauseActivityItem
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
// ......
// token 是一个索引值
// 通过 token 可以拿到 ActivityClientRecord,ActivityClientRecord 对象存在于 App 端的,用于描述描述一个 Activity
final IBinder token = transaction.getActivityToken();
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
+ lifecycleItem + " for activity: "
+ getShortActivityName(token, mTransactionHandler));
}
if (r == null) {
// Ignore requests for non-existent client records for now.
return;
}
// Cycle to the state right before the final requested state.
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
// Execute the final transition with proper parameters.
// 执行生命周期
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
// 执行生命周期后的操作也要关心
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
接着执行 PauseActivityItem 的 execute:
// /frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
// 执行回调
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
2
3
4
5
6
7
8
9
10
client 的具体类型是 ActivityThread 接着执行到 ActivityThread 的 handlePauseActivity 方法:
// /frameworks/base/core/java/android/app/ActivityThread.java
@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) { // 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;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
接着调用 performPauseActivity:
// /frameworks/base/core/java/android/app/ActivityThread.java
/**
* 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) {
//......
// 关注点
performPauseActivityIfNeeded(r, reason);
//......
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
接着调用 performPauseActivityIfNeeded
:
// /frameworks/base/core/java/android/app/ActivityThread.java
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
// ......
try {
r.activity.mCalled = false;
// 关注点
mInstrumentation.callActivityOnPause(r.activity);
if (!r.activity.mCalled) {
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
+ " did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException("Unable to pause activity "
+ safeToComponentShortString(r.intent) + ": " + e.toString(), e);
}
}
r.setState(ON_PAUSE);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
接着会调用 Activity 的 callActivityOnPause:
// /frameworks/base/core/java/android/app/Instrumentation.java
/**
* 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();
}
2
3
4
5
6
7
8
9
10
接着执行 Activity 的 performPause 方法:
// /frameworks/base/core/java/android/app/Activity.java
final void performPause() {
dispatchActivityPrePaused();
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
onPause();
writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
dispatchActivityPostPaused();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在这里就会执行到 Activity 的 onPause 生命周期方法。
生命周期执行完后,接下来回到之前的 executeLifecycleState 方法中:
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
// 拿到 ActivityLifecycleItem,这里是子类 PauseActivityItem
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
// ......
// 执行生命周期
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
2
3
4
5
6
7
8
9
10
11
在调用 execute
方法,执行完 onPause 生命周期方法后,接着会调用到 lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
// frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mDontReport) {
return;
}
// TODO(lifecycler): Use interface callback instead of actual implementation.
ActivityClient.getInstance().activityPaused(token);
}
2
3
4
5
6
7
8
9
10
在这里,会调用到 ActivityClient 的 activityPaused 方法。这部分内容我们就留在下一节在分析了。