Android源码分析 - Activity销毁流程

开篇

本篇以android-11.0.0_r25作为基础解析

我们在之前的几篇Activity启动流程分析中已经了解了Activity一半的生命周期,接下来这篇文章我们就来分析一下Activity销毁相关的生命周期

前几期文章回顾:

Android源码分析 - Activity启动流程(上)

Android源码分析 - Activity启动流程(中)

Android源码分析 - Activity启动流程(下)

触发销毁

既然要分析Activity销毁流程,那我们就从最常见的入口Activity.finish入手

1
2
3
public void finish() {
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}

默认的finish方法调用了另一个同名重载方法,接受一个int类型的参数表明是否需要在销毁Activity的同时销毁Task,该参数有以下三种:

  • DONT_FINISH_TASK_WITH_ACTIVITY:默认参数,表示在销毁Activity的时候不要销毁Task

  • FINISH_TASK_WITH_ROOT_ACTIVITY:当Activity为跟Activity的时候,销毁的同时销毁Task,同时这个任务也会从最近任务中移除

  • FINISH_TASK_WITH_ACTIVITY:销毁Activity的时候同时销毁Task,但不会从最近任务中移除

1
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
private void finish(int finishTask) {
if (mParent == null) {
//当finish后才可能会触发onActivityResult回调
//这里准备将result返回给之前调用startActivityForResult的Activity
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
try {
//两个Activity可能处于不同进程中,做进程间通信的准备
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
//调用ATMS销毁Activity
if (ActivityTaskManager.getService()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}

// Activity was launched when user tapped a link in the Autofill Save UI - Save UI must
// be restored now.
if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {
restoreAutofillSaveUi();
}
}

onActivityResult回调是在对应Activity resume时才可能触发,具体过程后面会分析,将ActivityRecord.TokenResult作为参数调用ATMS.finishActivity方法

1
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
96
97
98
99
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
// Refuse possible leaked file descriptors
//回传的ResultIntent中不允许包含fd,防止泄漏
if (resultData != null && resultData.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}

final ActivityRecord r;
synchronized (mGlobalLock) {
//获取ActivityRecord并保证其在栈中
r = ActivityRecord.isInStackLocked(token);
//为null说明已被移出ActivityStack,视作已被finish
if (r == null) {
return true;
}
}

// Carefully collect grants without holding lock
//检查调用方(即待finish的Activity)是否能授予result所对应Activity package访问uri的权限
final NeededUriGrants resultGrants = collectGrants(resultData, r.resultTo);

synchronized (mGlobalLock) {
// Sanity check in case activity was removed before entering global lock.
if (!r.isInHistory()) {
return true;
}

// Keep track of the root activity of the task before we finish it
final Task tr = r.getTask();
final ActivityRecord rootR = tr.getRootActivity();
// Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
// finish.
//LockTask模式下,如果此为最后一个Task,则不允许被销毁
//详见:https://developer.android.com/work/dpc/dedicated-devices/lock-task-mode
if (getLockTaskController().activityBlockedFromFinish(r)) {
return false;
}

// TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
// We should consolidate.
//IActivityController分发Activity状态变化
if (mController != null) {
// Find the first activity that is not finishing.
//寻找该Activity销毁后的下一个顶层Activity
final ActivityRecord next =
r.getRootTask().topRunningActivity(token, INVALID_TASK_ID);
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
try {
resumeOK = mController.activityResuming(next.packageName);
} catch (RemoteException e) {
mController = null;
Watchdog.getInstance().setActivityController(null);
}

if (!resumeOK) {
return false;
}
}
}

// note down that the process has finished an activity and is in background activity
// starts grace period
//设置Activity销毁的最新时间
if (r.app != null) {
r.app.setLastActivityFinishTimeIfNeeded(SystemClock.uptimeMillis());
}

final long origId = Binder.clearCallingIdentity();
try {
boolean res;
final boolean finishWithRootActivity =
finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
|| (finishWithRootActivity && r == rootR)) { //需要同时销毁Task
// If requested, remove the task that is associated to this activity only if it
// was the root activity in the task. The result code and data is ignored
// because we don't support returning them across task boundaries. Also, to
// keep backwards compatibility we remove the task from recents when finishing
// task with root activity.
//移除Task
mStackSupervisor.removeTask(tr, false /*killProcess*/,
finishWithRootActivity, "finish-activity");
res = true;
// Explicitly dismissing the activity so reset its relaunch flag.
r.mRelaunchReason = RELAUNCH_REASON_NONE;
} else { //不需要同时销毁Task
r.finishIfPossible(resultCode, resultData, resultGrants,
"app-request", true /* oomAdj */);
res = r.finishing;
}
return res;
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}

这个方法里分了两个case,当需要同时销毁Task的时候,直接调用ActivityStackSupervisor.removeTask,当不需要同时销毁Task的时候,调用ActivityRecord.finishIfPossible

我们先看需要同时销毁Task的case

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason) {
if (task.mInRemoveTask) {
// Prevent recursion.
return;
}
task.mInRemoveTask = true;
try {
//执行Task移除操作
task.performClearTask(reason);
//对Task执行杀进程,从最近任务列表移除等操作
cleanUpRemovedTaskLocked(task, killProcess, removeFromRecents);
//关闭LockTask模式
mService.getLockTaskController().clearLockedTask(task);
//通知Task状态发生变化
mService.getTaskChangeNotificationController().notifyTaskStackChanged();
//将最近任务持久化保存
if (task.isPersistable) {
mService.notifyTaskPersisterLocked(null, true);
}
} finally {
task.mInRemoveTask = false;
}
}

本篇文章我们主要关注的是Activity销毁流程,至于进程的关闭,最近任务列表的更新我们在这里就不关心了,而这里Activity销毁的重点在于Task.performClearTask方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/** Completely remove all activities associated with an existing task. */
void performClearTask(String reason) {
// Broken down into to cases to avoid object create due to capturing mStack.
if (getStack() == null) {
forAllActivities((r) -> {
if (r.finishing) return;
// Task was restored from persistent storage.
r.takeFromHistory();
removeChild(r);
});
} else {
forAllActivities((r) -> {
if (r.finishing) return;
// TODO: figure-out how to avoid object creation due to capture of reason variable.
r.finishIfPossible(Activity.RESULT_CANCELED,
null /* resultData */, null /* resultGrants */, reason, false /* oomAdj */);
});
}
}

我们看后半部分代码可以发现,这个方法对Task中所有未销毁的Activity都执行了ActivityRecord.finishIfPossible方法,这样路径就和上面ATMS.finishActivity方法中第二个case统一了

1
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
* Finish activity if possible. If activity was resumed - we must first pause it to make the
* activity below resumed. Otherwise we will try to complete the request immediately by calling
* {@link #completeFinishing(String)}.
* @return One of {@link FinishRequest} values:
* {@link #FINISH_RESULT_REMOVED} if this activity has been removed from the history list.
* {@link #FINISH_RESULT_REQUESTED} if removal process was started, but it is still in the list
* and will be removed from history later.
* {@link #FINISH_RESULT_CANCELLED} if activity is already finishing or in invalid state and the
* request to finish it was not ignored.
*/
@FinishRequest int finishIfPossible(int resultCode, Intent resultData,
NeededUriGrants resultGrants, String reason, boolean oomAdj) {

//防止重复销毁
if (finishing) {
return FINISH_RESULT_CANCELLED;
}

//此Activity不在任务栈中
if (!isInStackLocked()) {
return FINISH_RESULT_CANCELLED;
}

final ActivityStack stack = getRootTask();
//应该调整顶部Activity
final boolean mayAdjustTop = (isState(RESUMED) || stack.mResumedActivity == null)
&& stack.isFocusedStackOnDisplay();
//应该调整全局焦点
final boolean shouldAdjustGlobalFocus = mayAdjustTop
// It must be checked before {@link #makeFinishingLocked} is called, because a stack
// is not visible if it only contains finishing activities.
&& mRootWindowContainer.isTopDisplayFocusedStack(stack);

//暂停布局工作
mAtmService.deferWindowLayout();
try {
//设置当前Activity状态为finishing
makeFinishingLocked();
// Make a local reference to its task since this.task could be set to null once this
// activity is destroyed and detached from task.
final Task task = getTask();
//获取上一个ActivityRecord
ActivityRecord next = task.getActivityAbove(this);
//传递FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:重置该Task时清除此Activity
if (next != null) {
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
// If the caller asked that this activity (and all above it)
// be cleared when the task is reset, don't lose that information,
// but propagate it up to the next activity.
next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
}
}

//暂停输入事件分发
pauseKeyDispatchingLocked();

// We are finishing the top focused activity and its task has nothing to be focused so
// the next focusable task should be focused.
//应该调整顶部Activity,但此Task没有Activity可以被运行在顶部,将焦点转移至下一个可聚焦的Task
if (mayAdjustTop && ((ActivityStack) task).topRunningActivity(true /* focusableOnly */)
== null) {
task.adjustFocusToNextFocusableTask("finish-top", false /* allowFocusSelf */,
shouldAdjustGlobalFocus);
}

//将Result信息写入到对应ActivityRecord中,待后面resume的时候触发onActivityResult回调
finishActivityResults(resultCode, resultData, resultGrants);

//终止Task
final boolean endTask = task.getActivityBelow(this) == null
&& !task.isClearingToReuseTask();
final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
if (isState(RESUMED)) {
if (endTask) {
//通知Task移除已开始
mAtmService.getTaskChangeNotificationController().notifyTaskRemovalStarted(
task.getTaskInfo());
}
// Prepare app close transition, but don't execute just yet. It is possible that
// an activity that will be made resumed in place of this one will immediately
// launch another new activity. In this case current closing transition will be
// combined with open transition for the new activity.
//准备Activity转场动画
mDisplayContent.prepareAppTransition(transit, false);

// When finishing the activity preemptively take the snapshot before the app window
// is marked as hidden and any configuration changes take place
//更新Task快照
if (mAtmService.mWindowManager.mTaskSnapshotController != null) {
final ArraySet<Task> tasks = Sets.newArraySet(task);
mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks);
mAtmService.mWindowManager.mTaskSnapshotController
.addSkipClosingAppSnapshotTasks(tasks);
}

// Tell window manager to prepare for this one to be removed.
//设置可见性
setVisibility(false);

if (stack.mPausingActivity == null) {
//开始暂停此Activity
stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
null /* resuming */);
}

if (endTask) {
//屏幕固定功能
mAtmService.getLockTaskController().clearLockedTask(task);
// This activity was in the top focused stack and this is the last activity in
// that task, give this activity a higher layer so it can stay on top before the
// closing task transition be executed.
//更新窗口层级
if (mayAdjustTop) {
mNeedsZBoost = true;
mDisplayContent.assignWindowLayers(false /* setLayoutNeeded */);
}
}
} else if (!isState(PAUSING)) {
... //正常不会进入此case
}

return FINISH_RESULT_REQUESTED;
} finally {
//恢复布局工作
mAtmService.continueWindowLayout();
}
}

这个方法中,我们需要关注一下对于Result信息的处理,这里调用了finishActivityResults方法,将Result信息写入到对应ActivityRecord中,待后面resume的时候触发onActivityResult回调

1
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
/**
* Sets the result for activity that started this one, clears the references to activities
* started for result from this one, and clears new intents.
*/
private void finishActivityResults(int resultCode, Intent resultData,
NeededUriGrants resultGrants) {
// Send the result if needed
if (resultTo != null) {
if (resultTo.mUserId != mUserId) {
if (resultData != null) {
resultData.prepareToLeaveUser(mUserId);
}
}
if (info.applicationInfo.uid > 0) {
mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(resultGrants,
resultTo.getUriPermissionsLocked());
}
resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData);
resultTo = null;
}

// Make sure this HistoryRecord is not holding on to other resources,
// because clients have remote IPC references to this object so we
// can't assume that will go away and want to avoid circular IPC refs.
results = null;
pendingResults = null;
newIntents = null;
setSavedState(null /* savedState */);
}

//将Result结果添加到results列表中
void addResultLocked(ActivityRecord from, String resultWho,
int requestCode, int resultCode,
Intent resultData) {
ActivityResult r = new ActivityResult(from, resultWho,
requestCode, resultCode, resultData);
if (results == null) {
results = new ArrayList<ResultInfo>();
}
results.add(r);
}

这个方法很简单,就是将Result信息添加到ActivityRecord.results列表中

然后我们继续沿着finish主线链路走,后面有一个isState的判断,正常来说,ActivityRecordstate应该为RESUMED,具体为什么我们可以回顾一下之前分析的Activity启动流程,在ActivityStackSupervisor.realStartActivityLocked方法最后,会调用ActivityStack.minimalResumeActivityLocked,在这个方法中,会将ActivityRecordstate设置为RESUMED,由于ClientTransaction的执行是通过Handler.sendMessage进行的,所以早在Activity onCreate之前,ActivityRecord的状态就已经被设为了RESUMED

根据以上分析,我们会走进isState(RESUMED)这个case中,接着调用ActivityStack.startPausingLocked方法暂停Activity

1
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* Start pausing the currently resumed activity. It is an error to call this if there
* is already an activity being paused or there is no resumed activity.
*
* @param userLeaving True if this should result in an onUserLeaving to the current activity.
* @param uiSleeping True if this is happening with the user interface going to sleep (the
* screen turning off).
* @param resuming The activity we are currently trying to resume or null if this is not being
* called as part of resuming the top activity, so we shouldn't try to instigate
* a resume here if not null.
* @return Returns true if an activity now is in the PAUSING state, and we are waiting for
* it to tell us when it is done.
*/
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming) {
//已有Activity正在暂停中
if (mPausingActivity != null) {
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.
completePauseLocked(false, resuming);
}
}
//上一个已resume的Activity
ActivityRecord prev = mResumedActivity;

//既没有已resume的Activity,也没有正在resume的Activity
//从栈顶找一个Activity恢复
if (prev == null) {
if (resuming == null) {
mRootWindowContainer.resumeFocusedStacksTopActivities();
}
return false;
}

//不能暂停一个正在resume的Activity
if (prev == resuming) {
return false;
}

//设置各种状态
mPausingActivity = prev;
mLastPausedActivity = prev;
mLastNoHistoryActivity = prev.isNoHistory() ? prev : null;
prev.setState(PAUSING, "startPausingLocked");
prev.getTask().touchActiveTime();
clearLaunchTime(prev);

//更新统计信息
mAtmService.updateCpuStats();

boolean pauseImmediately = false;
... //当前流程下pauseImmediately始终为false

if (prev.attachedToProcess()) {
try {
//调度Pause生命周期事务
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}

// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
//获取Wakelock,确保设备awake状态直到下一个Activity启动
if (!uiSleeping && !mAtmService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}

if (mPausingActivity != null) {
// Have the window manager pause its key dispatching until the new
// activity has started. If we're pausing the activity just because
// the screen is being turned off and the UI is sleeping, don't interrupt
// key dispatch; the same activity will pick it up again on wakeup.
if (!uiSleeping) {
//暂停输入事件分发
prev.pauseKeyDispatchingLocked();
}

if (pauseImmediately) { //不会进入此case
// If the caller said they don't want to wait for the pause, then complete
// the pause now.
completePauseLocked(false, resuming);
return false;
} else {
//设置超时监听(500ms内没有完成便视为超时)
prev.schedulePauseTimeout();
return true;
}

} else {
// This activity failed to schedule the
// pause, so just treat it as being paused now.
//未能成功暂停此Activity,从栈顶找一个Activity恢复
if (resuming == null) {
mRootWindowContainer.resumeFocusedStacksTopActivities();
}
return false;
}
}

可以看到,和Activity启动流程类似,该方法里面调用了ClientLifecycleManager.scheduleTransaction方法来调度Activity暂停的生命周期,具体是怎样调度的可以看我之前的文章 Android源码分析 - Activity启动流程(下),里面分析了ClientTransaction事务是怎么被调度执行的

了解完后我们就可以知道,生命周期事务的执行也就相当于分别调用ActivityLifecycleItempreExecuteexecutepostExecute方法,而PauseActivityItem没有重写preExecute方法,所以我们就依次分析其executepostExecute方法就好了

1
2
3
4
5
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
}

ClientTransactionHandler这个我们之前说过,这是一个抽象类,被ActivityThread继承实现,所以这里实际上就是调用ActivityThread.handlePauseActivity方法

handlePauseActivity

1
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
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
...
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(r, finished, reason, pendingActions);

// Make sure any pending writes are now committed.
//确保所有全局任务都被处理完成
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
//更新标记
mSomeActivitiesChanged = true;
}
}

/**
* 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) {
... //异常状态检查
if (finished) {
r.activity.mFinished = true;
}

// Pre-Honeycomb apps always save their state before pausing
//是否需要保存状态信息(Android 3.0前无论是否finish都会触发保存)
final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
if (shouldSaveState) {
//回调Activity的onSaveInstanceState方法
callActivityOnSaveInstanceState(r);
}

performPauseActivityIfNeeded(r, reason);

...//回调OnActivityPausedListener,目前看来只有NFC部分有注册这个回调

... //Android 3.0之前的特殊处理

//返回保存状态的Bundle
return shouldSaveState ? r.state : null;
}

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
//已暂停,直接返回
if (r.paused) {
// You are already paused silly...
return;
}

// Always reporting top resumed position loss when pausing an activity. If necessary, it
// will be restored in performResumeActivity().
//报告resume状态变更
reportTopResumedActivityChanged(r, false /* onTop */, "pausing");

try {
r.activity.mCalled = false;
//回调Activity的onPause方法
mInstrumentation.callActivityOnPause(r.activity);
if (!r.activity.mCalled) {
//必须要调用super.onPause方法
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
+ " did not call through to super.onPause()");
}
} catch ...
//设置状态
r.setState(ON_PAUSE);
}

这一条调用链路看下来还是很简单的,和之前我们分析过的其他生命周期调用是一个套路,这里显示调用了callActivityOnSaveInstanceState方法保存状态信息

1
2
3
4
5
6
7
8
9
10
11
private void callActivityOnSaveInstanceState(ActivityClientRecord r) {
r.state = new Bundle();
r.state.setAllowFds(false);
if (r.isPersistable()) {
r.persistentState = new PersistableBundle();
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}
}

通过Instrumentation调用Activity.performSaveInstanceState方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
final void performSaveInstanceState(@NonNull Bundle outState) {
//分发PreSaveInstanceState事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPreSaveInstanceState回调
dispatchActivityPreSaveInstanceState(outState);
//回调onSaveInstanceState
onSaveInstanceState(outState);
//保存受管理的Dialog的状态
saveManagedDialogs(outState);
//共享元素动画相关
mActivityTransitionState.saveState(outState);
//保存权限请求状态
storeHasCurrentPermissionRequest(outState);
//分发PostSaveInstanceState事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPostSaveInstanceState回调
dispatchActivityPostSaveInstanceState(outState);
}

最终回调Activity.onSaveInstanceState方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void onSaveInstanceState(@NonNull Bundle outState) {
//保存窗口信息
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());

outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
//保存Fragment状态
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
//自动填充相关
if (mAutoFillResetNeeded) {
outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
getAutofillManager().onSaveInstanceState(outState);
}
//分发SaveInstanceState事件,执行所有注册的ActivityLifecycleCallbacks的onActivitySaveInstanceState回调
dispatchActivitySaveInstanceState(outState);
}

保存状态的流程就基本完成了,我们再回过头来看onPause的触发

在上面performPauseActivityIfNeeded方法中有一行代码调用了Instrumentation.callActivityOnPause方法,
通过Instrumentation调用了Activity.performPause方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
final void performPause() {
//分发PrePaused事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPrePaused回调
dispatchActivityPrePaused();
mDoReportFullyDrawn = false;
//FragmentManager分发pause状态
mFragments.dispatchPause();
mCalled = false;
//回调onPause
onPause();
mResumed = false;
//Target Sdk 9以上(Android 2.3)需要保证在onPause中调用super.onPause方法
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
//分发PostPaused事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPostPaused回调
dispatchActivityPostPaused();
}

执行onPause回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protected void onPause() {
//分发Paused事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPaused回调
dispatchActivityPaused();
//自动填充相关
if (mAutoFillResetNeeded) {
if (!mAutoFillIgnoreFirstResumePause) {
View focus = getCurrentFocus();
if (focus != null && focus.canNotifyAutofillEnterExitEvent()) {
getAutofillManager().notifyViewExited(focus);
}
} else {
// reset after first pause()
mAutoFillIgnoreFirstResumePause = false;
}
}
//内容捕获服务
notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_PAUSE);
//super.onPause标注为已被执行
mCalled = true;
}

到此为止,ActivityonPause生命周期已经基本走完了,此时我们再回到PauseActivityItem.postExecute方法中做一些善后处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
//mDontReport为我们之前obtain方法中传入的pauseImmediately参数,始终为false
if (mDontReport) {
return;
}
try {
// TODO(lifecycler): Use interface callback instead of AMS.
//调用ATMS.activityPaused方法
ActivityTaskManager.getService().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}

这里调用ATMS.activityPaused方法回到system_server进程处理Activity暂停后的事项

1
2
3
4
5
6
7
8
9
10
11
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized (mGlobalLock) {
//通过ActivityRecord.Token获取ActivityRecord
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
r.activityPaused(false);
}
}
Binder.restoreCallingIdentity(origId);
}

调用ActivityRecord.activityPaused方法继续处理

1
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
void activityPaused(boolean timeout) {
final ActivityStack stack = getStack();

if (stack != null) {
//移除超时监听
removePauseTimeout();

if (stack.mPausingActivity == this) {
//暂停布局工作
mAtmService.deferWindowLayout();
try {
stack.completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
} finally {
//恢复布局工作
mAtmService.continueWindowLayout();
}
return;
} else { //暂停Activity失败
if (isState(PAUSING)) {
setState(PAUSED, "activityPausedLocked");
if (finishing) {
completeFinishing("activityPausedLocked");
}
}
}
}

//更新Activity可见性
mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
}

正常情况下会进入到ActivityStack.completePauseLocked方法中,但在暂停Activity失败的情况下,如果当前状态为PAUSING,则直接将其状态置为PAUSED已暂停,如果被标记为finishing,则会调用ActivityRecord.completeFinishing继续finish流程,这其实和正常情况下的调用链路差不多,具体我们往下就能看到

1
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
void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;

if (prev != null) {
prev.setWillCloseOrEnterPip(false);
//之前的状态是否为正在停止
final boolean wasStopping = prev.isState(STOPPING);
//设置状态为已暂停
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) {
//继续finish流程
prev = prev.completeFinishing("completePausedLocked");
} else if (prev.hasProcess()) {
//Configuration发生变化时可能会设置这个flag
if (prev.deferRelaunchUntilPaused) {
// Complete the deferred relaunch that was waiting for pause to complete.
//等待暂停完成后relaunch Activity
prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch);
} else if (wasStopping) {
// We are also stopping, the stop request must have gone soon after the pause.
// We can't clobber it, because the stop confirmation will not be handled.
// We don't need to schedule another stop, we only need to let it happen.
//之前的状态为正在停止,将状态置回即可
prev.setState(STOPPING, "completePausedLocked");
} else if (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) {
// Clear out any deferred client hide we might currently have.
prev.setDeferHidingClient(false);
// If we were visible then resumeTopActivities will release resources before
// stopping.
//添加到stop列表中等待空闲时执行stop
prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */,
"completePauseLocked");
}
} else {
//App在pause过程中死亡
prev = null;
}
// It is possible the activity was freezing the screen before it was paused.
// In that case go ahead and remove the freeze this activity has on the screen
// since it is no longer visible.
if (prev != null) {
//停止屏幕冻结
prev.stopFreezingScreenLocked(true /*force*/);
}
//Activity暂停完毕
mPausingActivity = null;
}

//恢复前一个顶层Activity
if (resumeNext) {
final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) {
mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
} else {
checkReadyForSleep();
final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null;
if (top == null || (prev != null && top != prev)) {
// If there are no more activities available to run, do resume anyway to start
// something. Also if the top activity on the stack is not the just paused
// activity, we need to go ahead and resume it to ensure we complete an
// in-flight app switch.
mRootWindowContainer.resumeFocusedStacksTopActivities();
}
}
}

if (prev != null) {
//恢复按键分发
prev.resumeKeyDispatchingLocked();
... //更新统计信息
}

//更新Activity可见性
mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);

// Notify when the task stack has changed, but only if visibilities changed (not just
// focus). Also if there is an active pinned stack - we always want to notify it about
// task stack changes, because its positioning may depend on it.
//通知Task状态发生变化
if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
|| (getDisplayArea() != null && getDisplayArea().hasPinnedTask())) {
mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
}
}

可以看到,无论暂停成功与否,最后都会走到ActivityRecord.completeFinishing方法中

1
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
/**
* Complete activity finish request that was initiated earlier. If the activity is still
* pausing we will wait for it to complete its transition. If the activity that should appear in
* place of this one is not visible yet - we'll wait for it first. Otherwise - activity can be
* destroyed right away.
* @param reason Reason for finishing the activity.
* @return Flag indicating whether the activity was removed from history.
*/
ActivityRecord completeFinishing(String reason) {
... //状态检查

final boolean isCurrentVisible = mVisibleRequested || isState(PAUSED);
if (isCurrentVisible) {
... //更新Activity可见性
}

boolean activityRemoved = false;

// If this activity is currently visible, and the resumed activity is not yet visible, then
// hold off on finishing until the resumed one becomes visible.
// The activity that we are finishing may be over the lock screen. In this case, we do not
// want to consider activities that cannot be shown on the lock screen as running and should
// proceed with finishing the activity if there is no valid next top running activity.
// Note that if this finishing activity is floating task, we don't need to wait the
// next activity resume and can destroy it directly.
// TODO(b/137329632): find the next activity directly underneath this one, not just anywhere
final ActivityRecord next = getDisplayArea().topRunningActivity(
true /* considerKeyguardState */);
// isNextNotYetVisible is to check if the next activity is invisible, or it has been
// requested to be invisible but its windows haven't reported as invisible. If so, it
// implied that the current finishing activity should be added into stopping list rather
// than destroy immediately.
final boolean isNextNotYetVisible = next != null
&& (!next.nowVisible || !next.mVisibleRequested);

//如果此Activity当前可见,而要恢复的Activity还不可见,则推迟finish,直到要恢复的Activity可见为止
if (isCurrentVisible && isNextNotYetVisible) {
// Add this activity to the list of stopping activities. It will be processed and
// destroyed when the next activity reports idle.
//添加到stop列表中等待空闲时执行stop
addToStopping(false /* scheduleIdle */, false /* idleDelayed */,
"completeFinishing");
//设置状态为stop中
setState(STOPPING, "completeFinishing");
} else if (addToFinishingAndWaitForIdle()) {
// We added this activity to the finishing list and something else is becoming resumed.
// The activity will complete finishing when the next activity reports idle. No need to
// do anything else here.
//将此Activity添加到待finish列表中,等待空闲时执行finish
} else {
// Not waiting for the next one to become visible, and nothing else will be resumed in
// place of this activity - requesting destruction right away.
//立刻销毁此Activity
activityRemoved = destroyIfPossible(reason);
}

return activityRemoved ? null : this;
}

对于非锁屏状态且当前要销毁的Activity在前台的情况下,该Activity可见而待恢复的Activity尚不可见,此时优先完成待恢复Activityresume生命周期,等到之后空闲再去处理待销毁Activitydestroy生命周期

所以在面试中常问的ActivityB返回到A的生命周期顺序我们从这里就可以看出来,理解后我们就不用去死记硬背了:

B.onPause -> A.onRestart -> A.onResume -> B.onStop -> B.onDestory

对于锁屏状态或者要销毁的Activity不在前台的情况下,由于不需要立刻恢复Activity,所以可能会直接处理待销毁Activitydestroy生命周期

我们以第一种当前要销毁的Activity在前台的情况分析,此时会将这个Activity添加到stop列表中,并将状态设置为STOPPING,之后返回到ActivityStack.completePauseLocked方法中,继续执行resumeNext工作

resumeNext中会调用RootWindowContainer.resumeFocusedStacksTopActivities方法恢复栈顶Activity,由于这个方法之前已经在
Android源码分析 - Activity启动流程(上) 中分析过了,这里就不再赘述了,我们还是将目光放在销毁流程上

通过之前的文章,我们知道恢复Activity会调用到ActivityThread.handleResumeActivity方法,而当Activity恢复完毕后,此方法最后一行会向MessageQueue添加一个IdleHandler,关于IdleHandler这里就不再介绍了,这是每位Android开发都应该了解的东西

1
2
3
4
5
6
7
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
r.nextIdle = mNewActivities;
mNewActivities = r;
Looper.myQueue().addIdleHandler(new Idler());
}

这里的IdlerActivityThread的一个内部类

1
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
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
...
if (a != null) {
mNewActivities = null;
IActivityTaskManager am = ActivityTaskManager.getService();
ActivityClientRecord prev;
//遍历整条ActivityClientRecord.nextIdle链,依次调用ATMS.activityIdle
do {
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
...
return false;
}
}

这里会遍历整个进程内所有的ActivityClientRecord,并依次调用ATMS.activityIdle方法

1
2
3
4
5
6
7
8
9
10
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
...
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r == null) {
return;
}
mStackSupervisor.activityIdleInternal(r, false /* fromTimeout */,
false /* processPausingActivities */, config);
...
}

ActivityRecord.Token获取到ActivityRecord,接着调用ActivityStackSupervisor.activityIdleInternal方法

1
2
3
4
5
6
7
void activityIdleInternal(ActivityRecord r, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
...
// Atomically retrieve all of the other things to do.
processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
...
}

这里我们只需要重点关注processStoppingAndFinishingActivities这一个方法,从方法名我们也能看出来,它是用来处理Activity stopdestroy

1
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
/**
* Processes the activities to be stopped or destroyed. This should be called when the resumed
* activities are idle or drawn.
*/
private void processStoppingAndFinishingActivities(ActivityRecord launchedActivity,
boolean processPausingActivities, String reason) {
// Stop any activities that are scheduled to do so but have been waiting for the transition
// animation to finish.
ArrayList<ActivityRecord> readyToStopActivities = null;
for (int i = mStoppingActivities.size() - 1; i >= 0; --i) {
final ActivityRecord s = mStoppingActivities.get(i);
final boolean animating = s.isAnimating(TRANSITION | PARENTS,
ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS);
//不在动画中或者ATMS服务正在关闭
if (!animating || mService.mShuttingDown) {
//跳过正在pause的Activitiy
if (!processPausingActivities && s.isState(PAUSING)) {
// Defer processing pausing activities in this iteration and reschedule
// a delayed idle to reprocess it again
removeIdleTimeoutForActivity(launchedActivity);
scheduleIdleTimeout(launchedActivity);
continue;
}

if (readyToStopActivities == null) {
readyToStopActivities = new ArrayList<>();
}
//将准备好stop的Activitiy加入列表中
readyToStopActivities.add(s);

mStoppingActivities.remove(i);
}
}

final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
for (int i = 0; i < numReadyStops; i++) {
final ActivityRecord r = readyToStopActivities.get(i);
//Activity是否在任务栈中
if (r.isInHistory()) {
if (r.finishing) {
// TODO(b/137329632): Wait for idle of the right activity, not just any.
//被标记为finishing,尝试销毁Activity
r.destroyIfPossible(reason);
} else {
//否则仅仅只是stop Activity
r.stopIfPossible();
}
}
}

final int numFinishingActivities = mFinishingActivities.size();
if (numFinishingActivities == 0) {
return;
}

// Finish any activities that are scheduled to do so but have been waiting for the next one
// to start.
final ArrayList<ActivityRecord> finishingActivities = new ArrayList<>(mFinishingActivities);
mFinishingActivities.clear();
for (int i = 0; i < numFinishingActivities; i++) {
final ActivityRecord r = finishingActivities.get(i);
if (r.isInHistory()) {
//立刻执行Activity的销毁流程
r.destroyImmediately(true /* removeFromApp */, "finish-" + reason);
}
}
}

对于被标记为finishingActivity,调用destroyIfPossible方法销毁

1
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
/**
* Destroy and cleanup the activity both on client and server if possible. If activity is the
* last one left on display with home stack and there is no other running activity - delay
* destroying it until the next one starts.
*/
boolean destroyIfPossible(String reason) {
//设置状态
setState(FINISHING, "destroyIfPossible");

// Make sure the record is cleaned out of other places.
//确保此Activity已从待stop列表中移除
mStackSupervisor.mStoppingActivities.remove(this);

final ActivityStack stack = getRootTask();
final TaskDisplayArea taskDisplayArea = getDisplayArea();
final ActivityRecord next = taskDisplayArea.topRunningActivity();
final boolean isLastStackOverEmptyHome =
next == null && stack.isFocusedStackOnDisplay()
&& taskDisplayArea.getOrCreateRootHomeTask() != null;
if (isLastStackOverEmptyHome) {
// Don't destroy activity immediately if this is the last activity on the display and
// the display contains home stack. Although there is no next activity at the moment,
// another home activity should be started later. Keep this activity alive until next
// home activity is resumed. This way the user won't see a temporary black screen.
//如果Home栈存在且这是当前焦点栈中最后一个Activity,则不要立即销毁它
//将此Activity添加到待finish列表中,等待空闲时执行finish
addToFinishingAndWaitForIdle();
return false;
}
//设置finishing标记(之前设过了,这里是重复设置)
makeFinishingLocked();

//立刻执行Activity的销毁流程
final boolean activityRemoved = destroyImmediately(true /* removeFromApp */,
"finish-imm:" + reason);

// If the display does not have running activity, the configuration may need to be
// updated for restoring original orientation of the display.
//更新可见性和屏幕显示方向
if (next == null) {
mRootWindowContainer.ensureVisibilityAndConfig(next, getDisplayId(),
false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
//更新恢复栈顶Activity
if (activityRemoved) {
mRootWindowContainer.resumeFocusedStacksTopActivities();
}

return activityRemoved;
}

这里做了最后的一些判断,然后调用destroyImmediately方法,立刻执行Activity的销毁流程(这里和上一个方法processStoppingAndFinishingActivities中,待finish列表的处理是一样的)

1
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
/**
* Destroy the current CLIENT SIDE instance of an activity. This may be called both when
* actually finishing an activity, or when performing a configuration switch where we destroy
* the current client-side object but then create a new client-side object for this same
* HistoryRecord.
* Normally the server-side record will be removed when the client reports back after
* destruction. If, however, at this point there is no client process attached, the record will
* be removed immediately.
*
* @return {@code true} if activity was immediately removed from history, {@code false}
* otherwise.
*/
boolean destroyImmediately(boolean removeFromApp, String reason) {
//已经被销毁或正在被销毁,直接返回
if (isState(DESTROYING, DESTROYED)) {
return false;
}

boolean removedFromHistory = false;

//清理工作
cleanUp(false /* cleanServices */, false /* setState */);

if (hasProcess()) {
//清理更新工作
if (removeFromApp) {
app.removeActivity(this);
if (!app.hasActivities()) {
mAtmService.clearHeavyWeightProcessIfEquals(app);
// Update any services we are bound to that might care about whether
// their client may have activities.
// No longer have activities, so update LRU list and oom adj.
//更新进程信息
app.updateProcessInfo(true /* updateServiceConnectionActivities */,
false /* activityChange */, true /* updateOomAdj */,
false /* addPendingTopUid */);
}
}

boolean skipDestroy = false;

try {
//调度销毁生命周期事务
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
DestroyActivityItem.obtain(finishing, configChangeFlags));
} catch (Exception e) {
// We can just ignore exceptions here... if the process has crashed, our death
// notification will clean things up.
if (finishing) {
//从历史任务中移除
removeFromHistory(reason + " exceptionInScheduleDestroy");
removedFromHistory = true;
skipDestroy = true;
}
}

nowVisible = false;

// If the activity is finishing, we need to wait on removing it from the list to give it
// a chance to do its cleanup. During that time it may make calls back with its token
// so we need to be able to find it on the list and so we don't want to remove it from
// the list yet. Otherwise, we can just immediately put it in the destroyed state since
// we are not removing it from the list.
if (finishing && !skipDestroy) {
//设置状态
setState(DESTROYING,
"destroyActivityLocked. finishing and not skipping destroy");
//设置销毁超时回调
mAtmService.mH.postDelayed(mDestroyTimeoutRunnable, DESTROY_TIMEOUT);
} else {
//设置状态
setState(DESTROYED,
"destroyActivityLocked. not finishing or skipping destroy");
app = null;
}
} else {
// Remove this record from the history.
if (finishing) {
//没有绑定进程,从历史任务中移除
removeFromHistory(reason + " hadNoApp");
removedFromHistory = true;
} else {
//没有绑定进程且不在finishing中,直接设置状态为已被销毁
setState(DESTROYED, "destroyActivityLocked. not finishing and had no app");
}
}

configChangeFlags = 0;

return removedFromHistory;
}

scheduleTransaction

这个方法做了一些清理工作,重头戏在于调用了ClientLifecycleManager.scheduleTransaction方法调度销毁生命周期事务,接下来我们就重点分析这个事务的执行路径

scheduleTransaction的调用链路我们在 Android源码分析 - Activity启动流程(下) 中已经分析过了,这里我就简单的标注一下流程:

ClientLifecycleManager.scheduleTransaction ->
ClientTransaction.schedule ->
ActivityThread.scheduleTransaction ->
ClientTransaction.preExecute ->
ActivityLifecycleItem.preExecute->
ActivityThread.sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction) ->
TransactionExecutor.execute ->
TransactionExecutor.executeCallbacks ->
TransactionExecutor.executeLifecycleState ->
TransactionExecutor.cycleToPath ->
ActivityLifecycleItem.execute ->
ActivityLifecycleItem.postExecute

这里的链路基本上和Activity启动事务链路相差无几,甚至更短了(Activity销毁事务没有添加callback),所以没看过我上篇文章的强烈推荐去看一下,这里我就不再做分析了

我们从TransactionExecutor.cycleToPath开始,之前我们分析过,我们在事务中设置的ActivityLifecycleItem代表了Activity最终需要到达执行的生命周期,而中间的那些过渡生命周期就由cycleToPath方法推进执行,我们目前的生命周期状态为ON_PAUSE,而我们的目标生命周期为ON_DESTROY,中间还夹着一个ON_STOP,所以这个方法会帮我们执行ClientTransactionHandler.handleStopActivity方法,也就是ActivityThread.handleStopActivity方法

handleStopActivity

1
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
public void handleStopActivity(IBinder token, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest /* false */, String reason) {
final ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;

final StopInfo stopInfo = new StopInfo();
//执行onStop生命周期
performStopActivityInner(r, stopInfo, true /* saveState */, finalStateRequest,
reason);

//更新可见性
updateVisibility(r, false);

// Make sure any pending writes are now committed.
//确保所有全局任务都被处理完成
if (!r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}

//记录Stop信息(不过在后续销毁链路中似乎并没有被用到)
stopInfo.setActivity(r);
stopInfo.setState(r.state);
stopInfo.setPersistentState(r.persistentState);
pendingActions.setStopInfo(stopInfo);
mSomeActivitiesChanged = true;
}

接下来的路径就和其他生命周期差不多了,大部分内容我都用注释标注了,大家顺着往下看就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Core implementation of stopping an activity.
* @param r Target activity client record.
* @param info Action that will report activity stop to server.
* @param saveState Flag indicating whether the activity state should be saved.
* @param finalStateRequest Flag indicating if this call is handling final lifecycle state
* request for a transaction.
* @param reason Reason for performing this operation.
*/
private void performStopActivityInner(ActivityClientRecord r, StopInfo info,
boolean saveState, boolean finalStateRequest /* false */, String reason) {
if (r != null) {
... //异常状态处理

// One must first be paused before stopped...
//如果没有被暂停则先执行pause生命周期
performPauseActivityIfNeeded(r, reason);

... //设置描述(Activity.onCreateDescription)

//回调Activity的onStop方法
callActivityOnStop(r, saveState, reason);
}
}
1
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
/**
* Calls {@link Activity#onStop()} and {@link Activity#onSaveInstanceState(Bundle)}, and updates
* the client record's state.
* All calls to stop an activity must be done through this method to make sure that
* {@link Activity#onSaveInstanceState(Bundle)} is also executed in the same call.
*/
private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
// Before P onSaveInstanceState was called before onStop, starting with P it's
// called after. Before Honeycomb state was always saved before onPause.
//这里shouldSaveState为true,因为activity.mFinished早在performPauseActivity的时候就被设为了true
final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
&& !r.isPreHoneycomb();
//targetSdkVersion为Android P (Android 9)之前
final boolean isPreP = r.isPreP();
if (shouldSaveState && isPreP) {
callActivityOnSaveInstanceState(r);
}

try {
//执行stop生命周期
r.activity.performStop(r.mPreserveWindow, reason);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
//设置生命周期状态
r.setState(ON_STOP);

if (shouldSaveState && !isPreP) {
callActivityOnSaveInstanceState(r);
}
}
1
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
final void performStop(boolean preserveWindow, String reason) {
mDoReportFullyDrawn = false;
//Loader相关,详见https://developer.android.com/guide/components/loaders
mFragments.doLoaderStop(mChangingConfigurations /*retain*/);

// Disallow entering picture-in-picture after the activity has been stopped
//stop后禁用画中画
mCanEnterPictureInPicture = false;

if (!mStopped) {
//分发PreStopped事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPreStopped回调
dispatchActivityPreStopped();
//关闭所有子窗口
if (mWindow != null) {
mWindow.closeAllPanels();
}

// If we're preserving the window, don't setStoppedState to true, since we
// need the window started immediately again. Stopping the window will
// destroys hardware resources and causes flicker.
if (!preserveWindow && mToken != null && mParent == null) {
//设置停止状态,释放硬件资源,销毁Surface
WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
}

//FragmentManager分发stop状态
mFragments.dispatchStop();

mCalled = false;
//执行onStop回调
mInstrumentation.callActivityOnStop(this);
EventLogTags.writeWmOnStopCalled(mIdent, getComponentName().getClassName(), reason);
if (!mCalled) {
//必须要调用super.onStop方法
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStop()");
}

//释放Cursors
synchronized (mManagedCursors) {
final int N = mManagedCursors.size();
for (int i=0; i<N; i++) {
ManagedCursor mc = mManagedCursors.get(i);
if (!mc.mReleased) {
mc.mCursor.deactivate();
mc.mReleased = true;
}
}
}

mStopped = true;
//分发PostStopped事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPostStopped回调
dispatchActivityPostStopped();
}
mResumed = false;
}

通过Instrumentation执行onStop回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected void onStop() {
//ActionBar动画
if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
//共享元素动画
mActivityTransitionState.onStop();
//分发PostStopped事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPostStopped回调
dispatchActivityStopped();
mTranslucentCallback = null;
//super.onStop标注为已被执行
mCalled = true;

... //自动填充相关

mEnterAnimationComplete = false;
}

这样,一整个onStop生命周期就执行完成了,最后还剩下个onDestroy,根据之前写的事务调度链路,现在应该走到了DestroyActivityItem.execute方法

1
2
3
4
5
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
client.handleDestroyActivity(token, mFinished, mConfigChanges,
false /* getNonConfigInstance */, "DestroyActivityItem");
}

可以看到,实际上就直接调用了ActivityThread.handleDestroyActivity方法

handleDestroyActivity

1
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
public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
boolean getNonConfigInstance, String reason) {
//执行onDestroy生命周期
ActivityClientRecord r = performDestroyActivity(token, finishing,
configChanges, getNonConfigInstance, reason);
if (r != null) {
//清理之前设置的延时移除的window
cleanUpPendingRemoveWindows(r, finishing);
WindowManager wm = r.activity.getWindowManager();
View v = r.activity.mDecor;
if (v != null) {
if (r.activity.mVisibleFromServer) {
mNumVisibleActivities--;
}
IBinder wtoken = v.getWindowToken();
if (r.activity.mWindowAdded) {
if (r.mPreserveWindow) {
// Hold off on removing this until the new activity's
// window is being added.
r.mPendingRemoveWindow = r.window;
r.mPendingRemoveWindowManager = wm;
// We can only keep the part of the view hierarchy that we control,
// everything else must be removed, because it might not be able to
// behave properly when activity is relaunching.
//从DecorView中移除ContentView
r.window.clearContentView();
} else {
//立刻执行View的移除操作,释放硬件资源,销毁Surface,回调View.onDetachedFromWindow
wm.removeViewImmediate(v);
}
}
if (wtoken != null && r.mPendingRemoveWindow == null) {
//移除指定Window下的所有rootView
WindowManagerGlobal.getInstance().closeAll(wtoken,
r.activity.getClass().getName(), "Activity");
} else if (r.mPendingRemoveWindow != null) {
// We're preserving only one window, others should be closed so app views
// will be detached before the final tear down. It should be done now because
// some components (e.g. WebView) rely on detach callbacks to perform receiver
// unregister and other cleanup.
//移除指定Window下除了当前DecorView以外的所有rootView
WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
r.activity.getClass().getName(), "Activity");
}
r.activity.mDecor = null;
}
if (r.mPendingRemoveWindow == null) {
// If we are delaying the removal of the activity window, then
// we can't clean up all windows here. Note that we can't do
// so later either, which means any windows that aren't closed
// by the app will leak. Well we try to warning them a lot
// about leaking windows, because that is a bug, so if they are
// using this recreate facility then they get to live with leaks.
WindowManagerGlobal.getInstance().closeAll(token,
r.activity.getClass().getName(), "Activity");
}

// Mocked out contexts won't be participating in the normal
// process lifecycle, but if we're running with a proper
// ApplicationContext we need to have it tear down things
// cleanly.
//清理Context
Context c = r.activity.getBaseContext();
if (c instanceof ContextImpl) {
((ContextImpl) c).scheduleFinalCleanup(
r.activity.getClass().getName(), "Activity");
}
}
if (finishing) {
try {
//处理一些销毁后的事项,移除超时回调等
ActivityTaskManager.getService().activityDestroyed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}

Window这块的处理我目前也不太了解,等以后我学习了WMS那块再补吧

其他的和之前的套路一样,调用performDestroyActivity方法执行销毁Activity

1
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
/** Core implementation of activity destroy call. */
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
ActivityClientRecord r = mActivities.get(token);
Class<? extends Activity> activityClass = null;
if (r != null) {
activityClass = r.activity.getClass();
r.activity.mConfigChangeFlags |= configChanges;
if (finishing) {
r.activity.mFinished = true;
}

//如果没有被暂停则先执行pause生命周期
performPauseActivityIfNeeded(r, "destroy");

//如果没有被停职则先执行stop生命周期
if (!r.stopped) {
callActivityOnStop(r, false /* saveState */, "destroy");
}
if (getNonConfigInstance) {
... //getNonConfigInstance为false,这里不执行
}
try {
r.activity.mCalled = false;
//执行onDestroy回调
mInstrumentation.callActivityOnDestroy(r.activity);
//必须要调用super.onDestroy方法
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + safeToComponentShortString(r.intent) +
" did not call through to super.onDestroy()");
}
//关闭所有子窗口
if (r.window != null) {
r.window.closeAllPanels();
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
//设置生命周期状态
r.setState(ON_DESTROY);
}
//空闲时清理资源
schedulePurgeIdler();
// updatePendingActivityConfiguration() reads from mActivities to update
// ActivityClientRecord which runs in a different thread. Protect modifications to
// mActivities to avoid race.
synchronized (mResourcesManager) {
mActivities.remove(token);
}
//严格模式更新Activity计数器,与实际Activity数量对比,判断是否产生内存泄漏
StrictMode.decrementExpectedActivityCount(activityClass);
return r;
}

通过Instrumentation调用Activity.performDestroy方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
final void performDestroy() {
//分发PreDestroyed事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPreDestroyed回调
dispatchActivityPreDestroyed();
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy();
onDestroy();
EventLogTags.writeWmOnDestroyCalled(mIdent, getComponentName().getClassName(),
"performDestroy");
mFragments.doLoaderDestroy();
if (mVoiceInteractor != null) {
mVoiceInteractor.detachActivity();
}
//分发PostDestroyed事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPostDestroyed回调
dispatchActivityPostDestroyed();
}
1
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
protected void onDestroy() {
//super.onDestroy标注为已被执行
mCalled = true;

... //自动填充相关

// dismiss any dialogs we are managing.
//关闭所有被管理的Dialog
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}

// close any cursors we are managing.
//关闭所有被管理的Cursor
synchronized (mManagedCursors) {
int numCursors = mManagedCursors.size();
for (int i = 0; i < numCursors; i++) {
ManagedCursor c = mManagedCursors.get(i);
if (c != null) {
c.mCursor.close();
}
}
mManagedCursors.clear();
}

// Close any open search dialog
//关闭系统搜索服务的弹窗
if (mSearchManager != null) {
mSearchManager.stopSearch();
}

if (mActionBar != null) {
mActionBar.onDestroy();
}

//分发Destroyed事件,执行所有注册的ActivityLifecycleCallbacks的onActivityDestroyed回调
dispatchActivityDestroyed();

//内容捕获服务
notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_STOP);
}

DestroyActivityItem没有重写postExecute方法,所以到此为止,Activity整个销毁流程就结束了

Tips

我们通过本篇文章的分析,可以发现,触发Activity销毁后,onStoponDestroy这两个生命周期回调的触发时机是不确定的,如果有需求需要在确定Activity要被销毁后立刻执行,我们可以在onPause回调中调用Activity.isFinishing方法判断mFinished标志是否被置true,如果为true则可以判定这个Activity将被销毁

结尾

至此,Activity的启动流程和销毁流程我们都分析完了,后面应该暂时不会再写Activity相关的源码分析了

之后的一段时间,我可能会将我的精力投入到AIGC的技术调研中,Android源码分析这一系列的后续更新可能会放慢,希望大家多多谅解