忽然有一天,我想要做一件事:去代码中去验证那些曾经被"灌输"的理论。
-- 服装学院的IT男
本篇已收录于Activity短暂的一生系列欢迎一起学习讨论Android应用开发或者WMS
V:WJB6995
Q:707409815
正文
生命周期系列:
之前看过一遍流程的Events日志
// SystemService端创建TargetActivity (writeWmCreateActivity)
03-27 14:41:06.428 27889 28629 I wm_create_activity: [0,253598020,21,com.google.android.dialer/.extensions.GoogleDialtactsActivity,android.intent.action.MAIN,NULL,NULL,270532608]
// SystemService端触发SourceActivity的Pause (writeWmPauseActivity)
03-27 14:41:06.431 27889 28629 I wm_pause_activity: [0,51114540,com.android.launcher3/.uioverrides.QuickstepLauncher,userLeaving=true,pauseBackTasks]
// SourceActivity应用端将执行onPause (writeWmOnPausedCalled)
03-27 14:41:06.448 28606 28606 I wm_on_paused_called: [51114540,com.android.launcher3.uioverrides.QuickstepLauncher,performPause]
// SystemService端把SourceActivity添加进需要stop的集合 (writeWmAddToStopping)
03-27 14:41:06.459 27889 28630 I wm_add_to_stopping: [0,51114540,com.android.launcher3/.uioverrides.QuickstepLauncher,makeInvisible]
// SystemService端要真正触发TargetActivity启动 (writeWmRestartActivity)
03-27 14:41:06.487 27889 28630 I wm_restart_activity: [0,253598020,21,com.google.android.dialer/.extensions.GoogleDialtactsActivity]
// TargetActivity端将执行onCreate (writeWmOnCreateCalled)
03-27 14:41:06.769 3401 3401 I wm_on_create_called: [253598020,com.google.android.dialer.extensions.GoogleDialtactsActivity,performCreate]
// TargetActivity端将执行onStart (writeWmOnStartCalled)
03-27 14:41:06.900 3401 3401 I wm_on_start_called: [253598020,com.google.android.dialer.extensions.GoogleDialtactsActivity,handleStartActivity]
// TargetActivity端将执行Resume (writeWmOnResumeCalled)
03-27 14:41:06.911 3401 3401 I wm_on_resume_called: [253598020,com.google.android.dialer.extensions.GoogleDialtactsActivity,RESUME_ACTIVITY]
// SystemService端触发SourceActivity的stop (writeWmStopActivity)
03-27 14:41:07.097 27889 30491 I wm_stop_activity: [0,51114540,com.android.launcher3/.uioverrides.QuickstepLauncher]
// SourceActivity应用端将执行onStop (writeWmStopActivity)
03-27 14:41:07.119 28606 28606 I wm_on_stop_called: [51114540,com.android.launcher3.uioverrides.QuickstepLauncher,STOP_ACTIVITY_ITEM]
其中可以看到很早就打印了 "wm_add_to_stopping",但是 SourceActivity 真正执行 onPause ("wm_on_stop_called")却是在最后。
所以按照顺序,先看看 "wm_add_to_stopping"相关的逻辑。
整个流程分为3步:
-
- addToStopping 流程,将应用添加进需要stop的列表 -- system_service进程处理
-
- stopIfPossible 流程,也就是开始执行stop -- system_service进程处理
-
- 应用端处理stop流程 -- 应用进程处理
前面个都是system_service进程处理的,第三步是在 SourceActivity 的应用进程处理。
本篇为 onStop第一篇,介绍 system_service 进程是如何把 SourceActivity 添加进stop集合。
第一步:addToStopping 流程
1 调用链概览
通过Events日志可知"wm_add_to_stopping"的执行在真正启动 TargetActivity 之前。 在 SourceActivity 的 pause 流程之后。
"wm_add_to_stopping" 日志打印的方法在 ActivityRecord::addToStopping 中,在这个方法加上堆栈得到以下内容
03-28 14:39:03.326 23968 26756 I wm_add_to_stopping: [0,264636779,com.android.launcher3/.uioverrides.QuickstepLauncher,makeInvisible]
03-28 14:39:03.327 23968 26756 E biubiubiu: ActivityRecord addToStopping: ActivityRecord{fc6096b u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t7}
03-28 14:39:03.327 23968 26756 E biubiubiu: java.lang.Exception
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.ActivityRecord.addToStopping(ActivityRecord.java:6225)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.ActivityRecord.makeInvisible(ActivityRecord.java:5811)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState(EnsureActivitiesVisibleHelper.java:243)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.EnsureActivitiesVisibleHelper.process(EnsureActivitiesVisibleHelper.java:155)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.TaskFragment.updateActivityVisibilities(TaskFragment.java:1118)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.Task.lambda$ensureActivitiesVisible$19(Task.java:4918)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.Task$$ExternalSyntheticLambda24.accept(Unknown Source:10)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.Task.forAllLeafTasks(Task.java:3183)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.Task.forAllLeafTasks(Task.java:3171)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.Task.ensureActivitiesVisible(Task.java:4917)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.DisplayContent.lambda$ensureActivitiesVisible$44(DisplayContent.java:6143)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda38.accept(Unknown Source:10)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.Task.forAllRootTasks(Task.java:3195)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2033)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2033)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2033)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2033)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2033)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2033)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2026)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.DisplayContent.ensureActivitiesVisible(DisplayContent.java:6142)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1873)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:1854)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1802)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:6063)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:182)
03-28 14:39:03.327 23968 26756 E biubiubiu: at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:574)
03-28 14:39:03.327 23968 26756 E biubiubiu: at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:125)
03-28 14:39:03.327 23968 26756 E biubiubiu: at android.os.Binder.execTransactInternal(Binder.java:1280)
03-28 14:39:03.327 23968 26756 E biubiubiu: at android.os.Binder.execTransact(Binder.java:1244)
根据这段堆栈很明显可以看初是 SourceActivity 执行的 activityPaused 流程,再根据之前的Events日志顺序,也知道是在 SourceActivity 执行完 pause 流程后触发的。
也就是说 activityPaused 流程再触发 TargetActivity 启动前,还执行了 addToStopping 流程,将 SourceActivity 放进来需要 stop 的列表中。
关于 【Activity启动流程-2】流程之前整理的调用链如下:
ActivityClientController::activityPaused
ActivityRecord::activityPaused
TaskFragment::completePause
RootWindowContainer::resumeFocusedTasksTopActivities --分支1 ,再次执行 resumeFocusedTasksTopActivities
RootWindowContainer::resumeFocusedTasksTopActivities
Task::resumeTopActivityUncheckedLocked
Task::resumeTopActivityInnerLocked
TaskFragment::resumeTopActivity
ActivityTaskSupervisor::startSpecificActivity --触发 startSpecificActivity 判断应用是否创建
RootWindowContainer::ensureActivitiesVisible --分支2
RootWindowContainer::ensureActivitiesVisible
DisplayContent::ensureActivitiesVisible
WindowContainer::forAllRootTasks --忽略固定逻辑
Task::ensureActivitiesVisible
Task::forAllLeafTasks --忽略固定逻辑
TaskFragment::updateActivityVisibilities
EnsureActivitiesVisibleHelper::process
EnsureActivitiesVisibleHelper::setActivityVisibilityState
EnsureActivitiesVisibleHelper::makeVisibleAndRestartIfNeeded
ActivityTaskSupervisor::startSpecificActivity --触发 startSpecificActivity 判断应用是否创建
这2个分支在【Activity启动流程】都分析过了,但是现在关注的是生命周期相关, 分之一和生命周期相关的流程已经分析过了,现在需要看看分支2和生命周期相关的逻辑。
# TaskFragment
void completePause(boolean resumeNext, ActivityRecord resuming) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "completePause");
// 拿到之前的Activity,也就是需要 pause的
ActivityRecord prev = mPausingActivity;
ProtoLog.v(WM_DEBUG_STATES, "Complete pause: %s", prev);
if (prev != null) {
......
// 设置窗口状态为PAUSED
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) {
...... 如果已经finish,上面还在设置 pause,那正常应该是还没finish
} else if (prev.hasProcess()) {
// 打印状态日志
ProtoLog.v(WM_DEBUG_STATES, "Enqueue pending stop if needed: %s "
+ "wasStopping=%b visibleRequested=%b", prev, wasStopping,prev.mVisibleRequested);
}else {
......
}
if (resumeNext) {
......
// 重点* 第1分支
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "resumeFocusedTasksTopActivities");
mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev,null /* targetOptions */);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
......
}
......
// 重点* 第2分支
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "ensureActivitiesVisible");
mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
......
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
我在代码上加了几个 Trace 稍后再看,当前分析 onStop 流程所以只看第2分支触发的 ensureActivitiesVisible 流程,这个流程就是界面上有啥风吹草动,SystemService 端需要确保手机屏幕上Activity正确的显示。
根据上面的堆栈和整理出的调用链 RootWindowContainer::ensureActivitiesVisible 最终会执行到 EnsureActivitiesVisibleHelper::process 来处理当前 Task 下 Activity 的可见性。
EnsureActivitiesVisibleHelper的相关处理后面单独放一个章节详细解释,是ensureActivitiesVisible 流程非常重要的一环,目前可以自行了解或以黑盒概念理解
直接看 EnsureActivitiesVisibleHelper::setActivityVisibilityState 对 SourceActivity 的 stop 逻辑是如何处理的。
# EnsureActivitiesVisibleHelper
// 当前Task栈顶是否有Activity
private boolean mAboveTop;
// 设置Activity可见性
private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
final boolean resumeTopActivity) {
......
// SourceActivity 所在的Task 被遮挡了,所以mBehindFullyOccludedContainer为true
r.updateVisibilityIgnoringKeyguard(mBehindFullyOccludedContainer);
// 自然是返回不可见
final boolean reallyVisible = r.shouldBeVisibleUnchecked();
......
if (reallyVisible) {
// 忽略可见处理
} else {
if (DEBUG_VISIBILITY) {
Slog.v(TAG_VISIBILITY, "Make invisible? " + r
+ " finishing=" + r.finishing + " state=" + r.getState()
+ " containerShouldBeVisible=" + mContainerShouldBeVisible
+ " behindFullyOccludedContainer=" + mBehindFullyOccludedContainer
+ " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
}
// 不可见的处理 --使Activity不可见
r.makeInvisible();
}
......// launcher处理
}
所以执行 ActivityRecord::makeInvisible 方法开始设置 SourceActivity 不可见。
2 设置Activity不可见 -- ActivityRecord::makeInvisible
makeInvisible 方法触发的调用链:
ActivityRecord::makeInvisible
ActivityRecord::setVisibility -- setVisibility通用流程
ActivityRecord::setVisibility
ActivityRecord::setVisibleRequested
ActivityRecord::addToStopping
ActivityTaskSupervisor.mStoppingActivities::add --添加当前Activity到集合
ActivityTaskSupervisor::scheduleIdle -- 发送IDLE_NOW_MSG
--------------处理消息-------------------
ActivityTaskSupervisor$ActivityTaskSupervisorHandler::handleMessage
ActivityTaskSupervisor$ActivityTaskSupervisorHandler::handleMessageInner
ActivityTaskSupervisor$ActivityTaskSupervisorHandler::activityIdleFromMessage
ActivityTaskSupervisor::activityIdleInternal
ActivityTaskSupervisor::processStoppingAndFinishingActivities -- 热启动第一次执行到这时因条件不满足不会执行后续逻辑
看一下代码执行流程。
# ActivityRecord
void makeInvisible() {
// mVisibleRequested 为false表示当前 Activity 已经在处理可见性逻辑了,不需要执行后面的逻辑,
if (!mVisibleRequested) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + this);
return;
}
// Now for any activities that aren't visible to the user, make sure they no longer are
// keeping the screen frozen.
// 对于不可见的Activity,需要开始真正的处理了
if (DEBUG_VISIBILITY) {
Slog.v(TAG_VISIBILITY, "Making invisible: " + this + ", state=" + getState());
}
try {
final boolean canEnterPictureInPicture = checkEnterPictureInPictureState(
"makeInvisible", true /* beforeStopping */);
// Defer telling the client it is hidden if it can enter Pip and isn't current paused,
// stopped or stopping. This gives it a chance to enter Pip in onPause().
// 画中画相关
final boolean deferHidingClient = canEnterPictureInPicture
&& !isState(STARTED, STOPPING, STOPPED, PAUSED);
setDeferHidingClient(deferHidingClient);
// 重点* 1. 设置为不可见 ,会将 mVisibleRequested 设置为false
setVisibility(false);
switch (getState()) {
case STOPPING:
case STOPPED:
// Reset the flag indicating that an app can enter picture-in-picture once the
// activity is hidden
supportsEnterPipOnTaskSwitch = false;
break;
case RESUMED:
case INITIALIZING:
case PAUSING:
case PAUSED:
case STARTED:
// 重点* 2. 加入到Stop列表
addToStopping(true /* scheduleIdle */,
canEnterPictureInPicture /* idleDelayed */, "makeInvisible");
break;
default:
break;
}
} catch (Exception e) {
// Just skip on any failure; we'll make it visible when it next restarts.
Slog.w(TAG, "Exception thrown making hidden: " + intent.getComponent(), e);
}
}
-
- 调用 setVisibility 方法设置为不可见
-
- 根据 state 做了一些处理,STOPPING 和 STOPPED 的情况下就设置了一个画中画的标志位,其他的几个状态会执行 addToStopping
方法前面的 mVisibleRequested 唯一赋值的地方在 ActivityRecord::setVisibleRequested 方法中,值为可见性,所以这个变量表示: 当前Activity被设置的可见性的值。
makeInvisible 方法是要将 Activity 设置为不可见,所以方法开始的时候如果 mVisibleRequested 是 false, 说明已经在做这件事了, 就不需要执行后面的逻辑了。
然后中间有一段画中画的逻辑处理,这段当前不需要关注。
再下面就是getState() 的返回值处理,当前执行到这里的是 SourceActivity 的 activityPaused 流程,所以这里的 getState() 返回的是 PAUSED ,这个可以通过上面的log确认。
2.1 setVisibility 方法
看一眼 setVisibility方法主要做了什么
# ActivityRecord
void setVisibility(boolean visible, boolean deferHidingClient) {
......
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"setAppVisibility(%s, visible=%b): %s visible=%b mVisibleRequested=%b Callers=%s",
token, visible, appTransition, isVisible(), mVisibleRequested,
Debug.getCallers(6));
......
// 处理 DisplayContent 下的2个集合
displayContent.mOpeningApps.remove(this);
displayContent.mClosingApps.remove(this);
......
// 1. 给 mVisibleRequested 赋值
setVisibleRequested(visible);
......
// 2. 处理 DisplayContent 下的2个集合
if (visible) {
displayContent.mOpeningApps.add(this);
mEnteringAnimation = true;
} else if (mVisible) {
displayContent.mClosingApps.add(this);
mEnteringAnimation = false;
}
......
// 3. 提交可见性更新
commitVisibility(visible, true /* performLayout */);
updateReportedVisibilityLocked();
}
-
- 执行 setVisibleRequested 方法,内部会对 mVisibleRequested 变量赋值
-
- 处理 DisplayContent类维护的2个列表, 分别对应打开和关闭的应用(这个很重要)
-
- 执行 commitVisibility 方法,这里会最终可见性
继续看主流程 addToStopping 方法。
addToStopping 流程非常重要
3. ActivityRecord::addToStopping 方法
# ActivityRecord
final ActivityTaskSupervisor mTaskSupervisor;
void addToStopping(boolean scheduleIdle, boolean idleDelayed, String reason) {
if (!mTaskSupervisor.mStoppingActivities.contains(this)) {
// 打印 event日志
EventLogTags.writeWmAddToStopping(mUserId, System.identityHashCode(this),
shortComponentName, reason);
// 重点* 1. 唯一将Activity添加到 mStoppingActivities 集合中的代码
mTaskSupervisor.mStoppingActivities.add(this);
}
final Task rootTask = getRootTask();
......
if (scheduleIdle || forceIdle) {
// 打印Proto日志
ProtoLog.v(WM_DEBUG_STATES,
"Scheduling idle now: forceIdle=%b immediate=%b", forceIdle, !idleDelayed);
if (!idleDelayed) {
// 重点* 2. 一般都是立即执行,所以是走这(可见根据上面log的immediate值确认)
mTaskSupervisor.scheduleIdle();
} ......
} ......
}
这个方法做了2件事
-
- 将当前这个Activity 添加到 ActivityTaskSupervisor 下的 mStoppingActivities 集合
-
- 执行 ActivityTaskSupervisor::scheduleIdle 内部会发送 "IDLE_NOW_MSG" 消息,进而触发后续 stop 逻辑
这个方法正常是执行 scheduleIdle 逻辑的, 另外有 Events 和Proto 2个日志的打印,如果发现有问题可以仔细看看相关变量的打印。
ActivityTaskSupervisor::scheduleIdle 方法如下:
# ActivityTaskSupervisor
final void scheduleIdle() {
if (!mHandler.hasMessages(IDLE_NOW_MSG)) {
// 发送消息,打堆栈
if (DEBUG_IDLE) Slog.d(TAG_IDLE, "scheduleIdle: Callers=" + Debug.getCallers(4));
mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}
}
这个方法主要就是发送了"IDLE_NOW_MSG" 消息,并且打印了debug的堆栈。
冷启动的话 ActivityTaskSupervisor::scheduleIdle 的调用链就上面分析的一个,但是应用内启动Activity 根据log打印的堆栈发现会有3个调用链,这边也整理一下3个调用链,感兴趣的可以自己跟一下
Callers=com.android.server.wm.ActivityRecord.addToStopping:6239
com.android.server.wm.ActivityRecord.makeInvisible:5810
com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState:240
com.android.server.wm.EnsureActivitiesVisibleHelper.process:153
Callers=com.android.server.wm.ActivityTaskSupervisor.scheduleProcessStoppingAndFinishingActivitiesIfNeeded:2175
com.android.server.wm.ActivityRecord.onAnimationFinished:7473
com.android.server.wm.WindowContainer$$ExternalSyntheticLambda4.onAnimationFinished:2
com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$0$com-android-server-wm-SurfaceAnimator:133
Callers=com.android.server.wm.ActivityTaskSupervisor.scheduleProcessStoppingAndFinishingActivitiesIfNeeded:2175
com.android.server.wm.ActivityRecord.onWindowsVisible:6532
com.android.server.wm.ActivityRecord.updateReportedVisibilityLocked:6633
com.android.server.wm.WindowManagerService$4.onAppTransitionFinishedLocked:1154
4 "IDLE_NOW_MSG"的处理 ActivityTaskSupervisor -- activityIdleFromMessage
消息的执行也在 ActivityTaskSupervisor 类。
# ActivityTaskSupervisor
private final class ActivityTaskSupervisorHandler extends Handler {
@Override
public void handleMessage(Message msg) {
synchronized (mService.mGlobalLock) {
// 处理消息
if (handleMessageInner(msg)) {
return;
}
}
......
}
private boolean handleMessageInner(Message msg) {
......
case IDLE_NOW_MSG: {
if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
// 打印
activityIdleFromMessage((ActivityRecord) msg.obj, false /* fromTimeout */);
} break;
......
}
}
处理消息的时候也有log打印,"msg.obj" 为null。
继续看处理的代码
# ActivityTaskSupervisor
private void activityIdleFromMessage(ActivityRecord idleActivity, boolean fromTimeout) {
activityIdleInternal(idleActivity, fromTimeout,
fromTimeout /* processPausingActivities */, null /* config */);
}
void activityIdleInternal(ActivityRecord r, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
// 重点* 1 log
if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + r);
// 重点* 2. ActivityRecord 不为null才执行内部逻辑
if (r != null) {
// 重点* 3. log
if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternal: Callers="
+ Debug.getCallers(4));
......
}
......
// Atomically retrieve all of the other things to do. 原子检索所有其他要做的事情
// 重点* 4. 看方法名是处理 停止和finish的Activity辑在这里
processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
if (DEBUG_IDLE) {
// 重点* 5. log
Slogf.i(TAG, "activityIdleInternal(): r=%s, mStartingUsers=%s", r, mStartingUsers);
}
......
}
这里有5个重点,其中1,3,5都是log,很少会将log标记为重点,当前这么做是因为这个方法会执行两次,需要通过这3个log来区分
现在是分析第一次执行,根据前面的分析参数 r 是null,所以执行 processStoppingAndFinishingActivities 方法。
log中搜索"Activity idle: "可以有以下2次打印
Line 5664: 04-01 20:50:30.411 8585 8751 V ActivityTaskManager: Activity idle: null
Line 19079: 04-01 20:50:31.171 8585 9527 V ActivityTaskManager: Activity idle: ActivityRecord{95d53d7 u0 com.google.android.dialer/.extensions.GoogleDialtactsActivity} t26}
2次打印的行数和时间有很大的差距,说明不是一个时机执行的,当前分析的是第一次执行,是由 SourceActivity 执行 activityPaused 的时候会触发 addToStopping 流程。这一次参数 r 为null。
第二次打印的 r 为 TargetActivity 具体执行流程下面会分析。
4.1 processStoppingAndFinishingActivities 逻辑(其实啥也没干)
# ActivityTaskSupervisor
/**
* Processes the activities to be stopped or destroyed. This should be called when the resumed
* 处理要停止或销毁的Activity。这应该在resumed时调用
* activities are idle or drawn.
*/
private void processStoppingAndFinishingActivities(ActivityRecord launchedActivity,
boolean processPausingActivities, String reason) {
// 准备要执行 Stop 的Activity 集合
ArrayList<ActivityRecord> readyToStopActivities = null;
// 重点 * 1. 遍历mStoppingActivities
for (int i = mStoppingActivities.size() - 1; i >= 0; --i) {
// 获取到ActivityRecord (当前分析场景就1个)
final ActivityRecord s = mStoppingActivities.get(i);
final boolean animating = s.isAnimating(TRANSITION | PARENTS,
ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)
|| s.inTransition();
// 日志
ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
+ "finishing=%s", s, s.nowVisible, animating, s.finishing);
// 条件满足才执行
if (!animating || mService.mShuttingDown) {
......
// 打印 准备stop的log
ProtoLog.v(WM_DEBUG_STATES, "Ready to stop: %s", s);
if (readyToStopActivities == null) {
readyToStopActivities = new ArrayList<>();
}
// 重点 * 2. 添加进集合
readyToStopActivities.add(s);
// 从集合中移除
mStoppingActivities.remove(i);
}
}
// 重点 * 3. 遍历readyToStopActivities
final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
for (int i = 0; i < numReadyStops; i++) {
final ActivityRecord r = readyToStopActivities.get(i);
// 检查该ActivityRecord对象是否在历史记录中。
if (r.isInHistory()) {
// 如果该ActivityRecord对象正在结束(可能是用户或系统触发的结束操作)。
if (r.finishing) {
// TODO(b/137329632): Wait for idle of the right activity, not just any.
r.destroyIfPossible(reason);
} else {
// 重点* 4. 如果ActivityRecord对象不在结束状态,则尝试停止它
r.stopIfPossible();
}
}
}
......
}
这个方法的逻辑还是很重要的,不过当前这一次执行进来,因为条件不满足,其实相当于啥也没干。
-
- 这里遍历的集合,在 ActivityRecord::addToStopping 方法中看到对其赋值
-
- 满足条件的会被添加进 readyToStopActivities 集合, 进入if的条件刚好log也有打印
V WindowManager: Stopping ActivityRecord{f40797d u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t20}: nowVisible=true animating=true finishing=false mShuttingDown=false
animating 和 mShuttingDown 都不满足条件,所以不会进入。自如也不会有下面的"Ready to stop:"的打印,因为这里没进入执行 readyToStopActivities 集合没有元素,所以重点3也不会执行。
但是第二次执行 ActivityTaskSupervisor::activityIdleInternal 方法的时候的日志会有后续的打印,也就是说会执行到 ActivityRecord::stopIfPossible ,第二次的log如下
04-01 20:50:31.182 8585 9527 V WindowManager: Stopping ActivityRecord{f40797d u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t20}: nowVisible=false animating=false finishing=false mShuttingDown=false
04-01 20:50:31.182 8585 9527 V WindowManager: Ready to stop: ActivityRecord{f40797d u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t20}
第二次相关的逻辑有个印象几个,后面会再分析
5 小结
在正确冷启动流程的开始 SourceActivity 执行 activityPaused 的时候会触发 addToStopping 流程,这个流程会执行到 ActivityTaskSupervisor:: processStoppingAndFinishingActivities 方法,但是由于条件不满足,在这个方法中不会有什么实质性的处理。(后续还有会流程第二次触发该方法)
因此 addToStopping 流程最重要的事就是将 SourceActivity 添加到了 ActivityTaskSupervisor 类下的 mStoppingActivities 集合中。等后面条件满足再触发 ActivityTaskSupervisor:: processStoppingAndFinishingActivities 方法时就会执行 ActivityRecord::stopIfPossible 流程了。
"wm_add_to_stopping" 日志的线索跟到这里就结束了,后面的流程还有2个线索
-
- 第二个和 stop 有关的events 日志为 "wm_stop_activity" 并且已知在 "wm_on_resume_called"后打印
-
- ActivityTaskSupervisor::activityIdleInternal 的第二次执行,并且第二次执行到 ActivityTaskSupervisor::processStoppingAndFinishingActivities 方法会触发后续逻辑创建 Stop 的事务。