Activity 在以下几种情况下由于正常的应用操作会被销毁,例如:当用户按下后退键或者是 Activity 本身调用了 finish() 方法。此外,如果你的 Activity 生命周期处于 stop 状态而且一段时间内都没有被调用或者是处于前台的 Activity 需要更多的资源而系统资源紧张的时候,系统也会销毁你的 Activity,杀掉后台进程给前台进程留出足够的内存。下面我们来分析 Activity 的销毁流程。
涉及代码如下:
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/Instrumentation.java
frameworks/base/core/java/android/app/Activity.java
frameworks/base/core/java/android/app/FragmentController.java
frameworks/base/core/java/android/app/Activity.java
public void finish() {
// finish 当前 Activity,但不 finish 所在的 Task
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
private void finish(int finishTask) {
if (mParent == null) { // 父 Activity 为空
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
// 调用 ATMS.finishActivity
if (ActivityTaskManager.getService().finishActivity(
mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} else { // 如果父 Activity 非空,直接 finish 整个 Activity group
mParent.finishFromChild(this);
}
......
}
以下为是否 finishTask 的几个 flag 参数:
// 当 finish Activity 时,其所在的 Task 不 finish
public static final int DONT_FINISH_TASK_WITH_ACTIVITY = 0;
// 当 finish root Activity 时,其所在的 Task 也 finish, 且 Task 从最近任务列表移除
public static final int FINISH_TASK_WITH_ROOT_ACTIVITY = 1;
// 当 finish Activity 时,其所在的 Task 也 finish, 但 Task 不从最近任务列表移除
public static final int FINISH_TASK_WITH_ACTIVITY = 2;
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public final boolean finishActivity(IBinder token, int resultCode,
Intent resultData, int finishTask) {
synchronized (mGlobalLock) {
// 获取当前 ActivityRecord
ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return true;
}
// 获取当前 TaskRecord
final TaskRecord tr = r.getTaskRecord();
// 获取当前 ActivityRecord 的根 Activity
ActivityRecord rootR = tr.getRootActivity();
......
boolean res;
// 若当前 Activity 为根 Activity,判断是否 finish 根 Activity 所在的 task
final boolean finishWithRootActivity =
finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY ||
(finishWithRootActivity && r == rootR)) {
// finish 当前 task
res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
finishWithRootActivity, "finish-activity");
} else {
// finish 当前 Activity
res = tr.getStack().requestFinishActivityLocked(token, resultCode,
resultData, "app-request", true);
}
return res;
}
}
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
final boolean requestFinishActivityLocked(IBinder token,
int resultCode, Intent resultData, String reason, boolean oomAdj) {
// 先根据 token 获取 ActivityRecord,然后判断该 ActivityRecord
// 是否在其所属 Task 的 Activity 列表
ActivityRecord r = isInStackLocked(token);
if (r == null) {
return false;
}
finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
return true;
}
final boolean finishActivityLocked(ActivityRecord r, int resultCode,
Intent resultData, String reason, boolean oomAdj) {
// pauseImmediately 为 false
return finishActivityLocked(r, resultCode, resultData, reason,
oomAdj, !PAUSE_IMMEDIATELY);
}
final boolean finishActivityLocked(ActivityRecord r, int resultCode,
Intent resultData, String reason, boolean oomAdj,
boolean pauseImmediately) {
mWindowManager.deferSurfaceLayout();
try {
// 设置 Activity 的属性 finishing=true
r.makeFinishingLocked();
// 获取当前 task
final TaskRecord task = r.getTaskRecord();
// 获取当前 task 中所有 Activity
final ArrayList<ActivityRecord> activities = task.mActivities;
// 获取当前 Activity 的索引
final int index = activities.indexOf(r);
if (index < (activities.size() - 1)) {// 如果当前不是最后一个 Activity
task.setFrontOfTask();
if ((r.intent.getFlags() &
Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
// 如果当前 Activity 的 flags 为 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
// 则将该 flags 传递给下一个Activity
ActivityRecord next = activities.get(index+1);
next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
}
}
// 暂停 Key 分发事件
r.pauseKeyDispatchingLocked();
// 将当前 Activity 及其所在 Task 调整到最前面,使其 focused
adjustFocusedActivityStack(r, "finishActivity");
// 创建 ActivityResult, 并将其添加到启动当前 Activity
// 的那个 Activity 的 ActivityResult 列表 results
finishActivityResultsLocked(r, resultCode, resultData);
// 判断是否清除当前 task: 当前 Activity 位于栈底
// 且 Task 不复用时,则结束 Task
final boolean endTask = index <= 0 &&
!task.isClearingToReuseTask();
// 设置转换模式
final int transit = endTask ? TRANSIT_TASK_CLOSE :
TRANSIT_ACTIVITY_CLOSE;
if (mResumedActivity == r) { // 当前 Activity 为 Resumed 状态
if (endTask) {
// 通知 listeners 当前 Task 即将被移除
mService.getTaskChangeNotificationController().
notifyTaskRemovalStarted(task.getTaskInfo());
}
getDisplay().mDisplayContent.prepareAppTransition(transit, false);
// 设置 Activity 不可见,告诉 WindowManager 当前 Activity 即将被移除
r.setVisibility(false);
if (mPausingActivity == null) {
// 执行 pause 操作.
startPausingLocked(false, false, null, pauseImmediately);
}
if (endTask) {
// 清除当前 Task
mService.getLockTaskController().clearLockedTask(task);
}
} else if (!r.isState(PAUSING)) { // 当前 Activity 非 Pausing 状态
// If the activity is PAUSING, we will complete the finish once
// it is done pausing; else we can just directly finish it here.
if (r.visible) {
// 设置 Activity 为不可见
prepareActivityHideTransitionAnimation(r, transit);
}
// 设置 finishMode
final int finishMode = (r.visible || r.nowVisible) ?
FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE;
// finish 当前 Activity
final boolean removedActivity =
finishCurrentActivityLocked(r, finishMode, oomAdj,
"finishActivityLocked") == null;
if (task.onlyHasTaskOverlayActivities(true)) {
for (ActivityRecord taskOverlay : task.mActivities) {
if (!taskOverlay.mTaskOverlay) {
continue;
}
prepareActivityHideTransitionAnimation(
taskOverlay, transit);
}
}
return removedActivity;
}
return false;
} finally {
mWindowManager.continueSurfaceLayout();
}
}
private void finishActivityResultsLocked(ActivityRecord r,
int resultCode, Intent resultData) {
// resultTo 为 startActivity 时启动当前 Activity 的那个
// Activity (当前 Activity 的结果发给这个 Activity)
ActivityRecord resultTo = r.resultTo;
if (resultTo != null) {
if (resultTo.mUserId != r.mUserId) {
if (resultData != null) {
resultData.prepareToLeaveUser(r.mUserId);
}
}
if (r.info.applicationInfo.uid > 0) {
// 授予 Uri 权限
mService.mUgmInternal.grantUriPermissionFromIntent(
r.info.applicationInfo.uid,
resultTo.packageName, resultData,
resultTo.getUriPermissionsLocked(), resultTo.mUserId);
}
// 创建 ActivityResult, 并添加到 resultTo 的 ActivityResult 列表 results
resultTo.addResultLocked(r, r.resultWho,
r.requestCode, resultCode, resultData);
r.resultTo = null;
}
// 当前 Activity 属性置空
r.results = null;
r.pendingResults = null;
r.newIntents = null;
r.icicle = null;
}
frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
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);
}
// 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.
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
// 如果当前有 pausing 状态的 Activity(即 mPausingActivity 非空),
// 则完成 Pause 过程
if (mPausingActivity != null) {
if (!shouldSleepActivities()) {
completePauseLocked(false, resuming);
}
}
ActivityRecord prev = mResumedActivity;
// Trying to pause when nothing is resumed
// 我理解这段代码含义: 当前没有 resume 状态的 Activity, 说明这是一个 resume 过程
// 因此 resume top activity, 然后直接 return false. 正常的 Pause 走不到这里
if (prev == null && resuming == null) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
return false;
}
// Trying to pause activity that is in process of being resumed
if (prev == resuming) {
return false;
}
// 将之前 Resumed Activity 设置为当前 Paused Activity
mPausingActivity = prev;
mLastPausedActivity = prev;
mLastNoHistoryActivity = (prev.intent.getFlags() &
Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ?
prev : null;
// 设置 Activity 状态为 Pausing
prev.setState(PAUSING, "startPausingLocked");
......
if (prev.attachedToProcess()) { // 进程非空
// 执行 PauseActivityItem 事务
mService.getLifecycleManager().scheduleTransaction(
prev.app.getThread(), prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} 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.
if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}
if (mPausingActivity != null) {
if (!uiSleeping) {
prev.pauseKeyDispatchingLocked();
}
if (pauseImmediately) { // 立即 pause
completePauseLocked(false, resuming);
return false;
} else { // 500ms延时再pause
schedulePauseTimeout(prev);
return true;
}
} else { // Pause 失败
// This activity failed to schedule the pause,
// so just treat it as being paused now.
if (resuming == null) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return false;
}
}
frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
public class PauseActivityItem extends ActivityLifecycleItem {
@Override
public void execute(ClientTransactionHandler client,
IBinder token, PendingTransactionActions pendingActions) {
client.handlePauseActivity(token, mFinished,
mUserLeaving, mConfigChanges, pendingActions, "PAUSE_ACTIVITY_ITEM");
}
@Override
public int getTargetState() {
return ON_PAUSE;
}
@Override
public void postExecute(ClientTransactionHandler client,
IBinder token, PendingTransactionActions pendingActions) {
ActivityTaskManager.getService().activityPaused(token);
}
}
回调通知 client 进程,调用 Activity 的 onPause 方法,client 执行完成后,就会调用通知 ATMS,这个流程我们之前在分析 Activity 的启动流程中已经详细分析过了,可以参考 Android四大组件系列2 Activity启动流程(上) 。继续进入 ATMS 的 activityPaused 方法:
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public final void activityPaused(IBinder token) {
synchronized (mGlobalLock) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
}
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
final void activityPausedLocked(IBinder token, boolean timeout) {
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) { // 继续完成 pause 操作
completePauseLocked(true, null);
return;
} else {
if (r.isState(PAUSING)) { // pause 失败的 Activity,直接 finish 掉
r.setState(PAUSED, "activityPausedLocked");
if (r.finishing) {
finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE,
false, "activityPausedLocked");
}
}
}
}
mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
}
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (prev != null) {
prev.setWillCloseOrEnterPip(false);
// wasStopping 为 false
final boolean wasStopping = prev.isState(STOPPING);
// 设置 Activity 状态为 PAUSED
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) { // 会走到这里
// 关键点1 finish Activity
prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE,
false, "completePausedLocked");
} else if (prev.hasProcess()) {
if (prev.deferRelaunchUntilPaused) {
prev.relaunchActivityLocked(false /* andResume */,
prev.preserveWindowOnDeferredRelaunch);
} else if (wasStopping) {
prev.setState(STOPPING, "completePausedLocked");
} else if (!prev.visible || 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.
addToStopping(prev, true /* scheduleIdle */,
false /* idleDelayed */, "completePauseLocked");
}
} else { // App died during pause, not stopping
prev = null;
}
if (prev != null) {
prev.stopFreezingScreenLocked(true /*force*/);
}
mPausingActivity = null;
}
if (resumeNext) { // 是否恢复下一个 Activity
final ActivityStack topStack =
mRootActivityContainer.getTopDisplayFocusedStack();
if (!topStack.shouldSleepOrShutDownActivities()) {
// 关键点2:如果没有休眠和关机时,恢复顶层 Activity
// 也就是 resume 下个页面
mRootActivityContainer.resumeFocusedStacksTopActivities(
topStack, prev, null);
} else {
// 等待休眠完成,再恢复顶层 Activity
checkReadyForSleep();
ActivityRecord top = topStack.topRunningActivityLocked();
if (top == null || (prev != null && top != prev)) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
}
}
......
mRootActivityContainer.ensureActivitiesVisible(
resuming, 0, !PRESERVE_WINDOWS);
}
此时第一步,会调用自身的 finishCurrentActivityLocked 方法,第二步调用 RootActivityContainer 的 resumeFocusedStacksTopActivities。下面先看第一步的调用流程:
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
int mode, boolean oomAdj, String reason) {
final ActivityDisplay display = getDisplay();
// 获取下一个 Activity
final ActivityRecord next =
display.topRunningActivity(true);
final boolean isFloating =
r.getConfiguration().windowConfiguration.tasksAreFloating();
// 如果 mode 为 FINISH_AFTER_VISIBLE 且下一个 Activity 不可见(默认即为此),
// 则先将当前 Activity 添加到 stopping 列表,并将其状态设置为 STOPPING
// 等下一个 Activity 可见后再 finish 当前 Activity
if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
&& next != null && !next.nowVisible && !isFloating) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
// 添加到 stopping 列表.
addToStopping(r, false /* scheduleIdle */,
false /* idleDelayed */, "finishCurrentActivityLocked");
}
// Activity 状态设置为 STOPPING
r.setState(STOPPING, "finishCurrentActivityLocked");
if (oomAdj) {
mService.updateOomAdj();
}
return r;
}
// make sure the record is cleaned out of other places.
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
// 获取当前状态
final ActivityState prevState = r.getState();
// Activity 状态设置为 FINISHING
r.setState(FINISHING, "finishCurrentActivityLocked");
// 如果没有要显示的下一个 Activity 且当前显示的栈中包含 Home 栈,
// 则先等 HomeActivity 恢复之后
// 再销毁当前 Activity 这样做的目的是避免出现临时黑屏
final boolean noRunningStack = next == null &&
display.topRunningActivity() == null &&
display.getHomeStack() == null;
final boolean noFocusedStack = r.getActivityStack() !=
display.getFocusedStack();
final boolean finishingInNonFocusedStackOrNoRunning = mode ==
FINISH_AFTER_VISIBLE &&
prevState == PAUSED && (noFocusedStack || noRunningStack);
if (mode == FINISH_IMMEDIATELY
|| (prevState == PAUSED && (mode == FINISH_AFTER_PAUSE ||
inPinnedWindowingMode()))
|| finishingInNonFocusedStackOrNoRunning
|| prevState == STOPPING
|| prevState == STOPPED
|| prevState == ActivityState.INITIALIZING) {
// 设置 finishing=true
r.makeFinishingLocked();
// 销毁当前 Activity
boolean activityRemoved = destroyActivityLocked(
r, true, "finish-imm:" + reason);
if (finishingInNonFocusedStackOrNoRunning) {
mRootActivityContainer.ensureVisibilityAndConfig(
next, mDisplayId,
false /* markFrozenIfConfigChanged */, true);
}
if (activityRemoved) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return activityRemoved ? null : r;
}
if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
mStackSupervisor.mFinishingActivities.add(r);
r.resumeKeyDispatchingLocked();
mRootActivityContainer.resumeFocusedStacksTopActivities();
if (r.isState(RESUMED) && mPausingActivity != null) {
startPausingLocked(false /* userLeaving */, false,
next /* resuming */, false /* dontWait */);
}
return r;
}
以下为 finishMode:
// 立刻 finish 当前 Activity
static final int FINISH_IMMEDIATELY = 0;
// 当前 Activity pause 后 finish
static final int FINISH_AFTER_PAUSE = 1;
// 下一个要显示的 Activity 可见后再 finish 当前 Activity
static final int FINISH_AFTER_VISIBLE = 2;
此时会进入第一个 if 判断中,执行 addToStopping 方法,并不会调用下面的 destroyActivityLocked 的方法。
private void addToStopping(ActivityRecord r, boolean scheduleIdle,
boolean idleDelayed, String reason) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
// 将当前 Activity 添加到 stopping 列表
mStackSupervisor.mStoppingActivities.add(r);
}
// 如果 stopping 列表超出最大值,或者当前 Activity 为所在 Task 的根 Activity
// 且任务历史列表只剩这一个 Task 则先保持 idle,暂时不做什么
boolean forceIdle = mStackSupervisor.mStoppingActivities.size() >
MAX_STOPPING_TO_FORCE
|| (r.frontOfTask && mTaskHistory.size() <= 1);
if (scheduleIdle || forceIdle) {
if (!idleDelayed) {
mStackSupervisor.scheduleIdleLocked();
} else {
mStackSupervisor.scheduleIdleTimeoutLocked(r);
}
} else { // sleep
checkReadyForSleep();
}
}
addToStopping 的第一步操作就是把此将要 finish 的 Activity 加入到 stopping 列表,第二步是发送一个超时消息,如果 10S 后,此消息没有被移除,就会触发执行。
final void scheduleIdleLocked() {
mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}
private final class ActivityStackSupervisorHandler extends Handler {
public ActivityStackSupervisorHandler(Looper looper) {
super(looper);
}
void activityIdleInternal(ActivityRecord r,
boolean processPausingActivities) {
synchronized (mService.mGlobalLock) {
activityIdleInternalLocked(r != null ? r.appToken : null, true,
processPausingActivities, null);
}
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
......
case IDLE_TIMEOUT_MSG: {
activityIdleInternal((ActivityRecord) msg.obj,
true /* processPausingActivities */);
} break;
case IDLE_NOW_MSG: {
activityIdleInternal((ActivityRecord) msg.obj,
false /* processPausingActivities */);
} break;
......
}
}
启动 Activity 时会先去暂停当前显示的 Activity,当待启动 Activity 启动完成时回调 AMS 的 activityIdleInternalLocked() 函数。在该函数中会执行内存回收操作。
activityIdleInternalLocked() 函数内部依次处理 stop、finish 状态的 Activity,最后会执行到 AMS 的 trimApplications(),在该函数中执行内存回收。
activityIdleInternalLocked() 是执行内存回收的关键函数。
activityIdleInternalLocked() 被调用的时机:
顺便多说明以下,执行 AMS.trimApplications() 的过程:
下面再来看下 ActivityStack.completePauseLocked 方法中,第二步调用 RootActivityContainer 的 resumeFocusedStacksTopActivities 方法流程,目的是在 finish 此 Activity 之前,先去把下一个要显示的 Activity 设置为 resume 状态。
boolean resumeFocusedStacksTopActivities(ActivityStack targetStack,
ActivityRecord target, ActivityOptions targetOptions) {
if (!mStackSupervisor.readyToResume()) {
return false;
}
boolean result = false;
if (targetStack != null && (targetStack.isTopStackOnDisplay()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(
target, targetOptions);
}
......
return result;
}
根据之前分析的 Activity 的启动流程,我们知道这个方法最终会调用到 ActivityStack 的 resumeTopActivityInnerLocked。我们直接来看这个方法。
private boolean resumeTopActivityInnerLocked(ActivityRecord prev,
ActivityOptions options) {
......
// 从任务历史列表 mTaskHistory 里, 获取最上面运行的 Activity
ActivityRecord next = topRunningActivityLocked(true);
final boolean hasRunningActivity = next != null;
if (!hasRunningActivity) {
// 如果没有运行的 Activity, 则从其他 task 堆栈中查找 Activity 并 resume
return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
}
// 如果 topRunningActivity 已经是 resume 状态, 则 do nothing
if (mResumedActivity == next && next.isState(RESUMED) &&
display.allResumedActivitiesComplete()) {
executeAppTransition(options);
return false;
}
......
// 如果没有获取到 topRunningActivity,则先暂停所有 Stack 中的 Activity.
// 前面就是在这个方法中判断需要先 pause 当前 Activity 的
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
// 暂停当前恢复态的 Activity(mResumedActivity),注意 prev/next 为要启动的
// 目的 Activity, 而 mResumedActivity 为当前 Activity, 两者不是同一个
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false, next, false);
}
if (pausing && !resumeWhilePausing) {
// 如果 Activity 正在 Pausing 状态,且不允许 pausing 过程中执行 resume,
// 则先不执行 resume 只是将即将启动的 Activity 所在的进程添加到
// mLruProcesses 最前面, 避免被杀
if (next.attachedToProcess()) {
next.app.updateProcessInfo(false, true, false);
}
if (lastResumed != null) {
lastResumed.setWillCloseOrEnterPip(true);
}
return true;
} else if (mResumedActivity == next && next.isState(RESUMED) &&
display.allResumedActivitiesComplete()) {
// 如果要启动的 Activity 已经 Resume 了则不需要做什么
// 调一下 executeAppTransition 执行一下 pending transitions 即可.
executeAppTransition(options);
return true;
}
......
// 如果下一个 Activity 已经可见了, 上一个 Activity 当前正处于 finishing 状态
// 则直接让上一个 Activity 不可见,当上一个 Activity 不是 finishing 状态
//(比如当下一个 Activity 不是全屏状态时的场景), 上一个 Activity 还应该是可见的
if (prev != null && prev != next && next.nowVisible) {
if (prev.finishing) {
prev.setVisibility(false);
}
}
......
if (next.attachedToProcess()) {// 会走这个分支
// Activity 所在进程已启动, 和 realStartActivityLocked 做的事情类似.
// 上一个 Activity 是否半透明
final boolean lastActivityTranslucent = lastFocusedStack != null
&& (lastFocusedStack.inMultiWindowMode()
|| (lastFocusedStack.mLastPausedActivity != null
&& !lastFocusedStack.mLastPausedActivity.fullscreen));
// 如果将要启动的 Activity 不可见, 则让该 Activity 可见
if (!next.visible || next.stopped || lastActivityTranslucent) {
next.setVisibility(true);
}
......
// 设置 Activity 状态为 RESUMED
next.setState(RESUMED, "resumeTopActivityInnerLocked");
// 更新进程信息
next.app.updateProcessInfo(false, true, true);
......
// 关键点1:生成 ClientTransaction
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.appToken);
// 分发所有 pending 结果
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing && N > 0) {
transaction.addCallback(ActivityResultItem.obtain(a));
}
}
// 分发 new intent
if (next.newIntents != null) {
transaction.addCallback(
NewIntentItem.obtain(next.newIntents, true));
}
// Well the app will no longer be stopped.
// Clear app token stopped state in window manager if needed.
next.notifyAppResumed(next.stopped);
next.sleeping = false;
mService.getAppWarningsLocked().onResumeActivity(next);
next.app.setPendingUiCleanAndForceProcessStateUpTo(mService.mTopProcessState);
next.clearOptionsLocked();
// 关键点2:触发 onResume
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
getDisplay().mDisplayContent.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
// From this point on, if something goes wrong there is no way
// to recover the activity.
next.completeResumeLocked();
} else {// 进程没启动,不会走这里
......
}
return true;
}
和 Activity 启动过程类似,最终会将要显示的 Activity 置为 resume 状态。这里需要关注的是 ActivityThread 的 handleResumeActivity 方法。我们来看这个方法的最后一句代码:
public void handleResumeActivity(IBinder token, boolean finalStateRequest,
boolean isForward, String reason) {
......
Looper.myQueue().addIdleHandler(new Idler());
}
可以看到,在 handleResumeActivity 方法的最后一句,生成了一个 Idler 对象,并添加到了消息队列中,熟悉消息机制的同学们应该知道,在没有消息执行的情况下,就会执行这个 Idler 对象的 queueIdle 回调方法。不熟悉的可以参考 Android消息机制1 (Java层)。
也就是说:上一个将要显示的 Activity 被 resume 后,会进入 idle 状态,即调用到了 client 的 Idler.queueIdle 方法中,此方法内部接着调用了 ATMS 的 activityIdle 方法,目的是把之前加入到 stopping 列表中的将要 finish 的 Activity,去进行真正的销毁操作:
ActivityThread.java
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
boolean stopProfiling = false;
if (mBoundApplication != null && mProfiler.profileFd != null
&& mProfiler.autoStopProfiler) {
stopProfiling = true;
}
if (a != null) {
mNewActivities = null;
IActivityTaskManager am = ActivityTaskManager.getService();
ActivityClientRecord prev;
do {
if (localLOGV) Slog.v(
TAG, "Reporting idle of " + a +
" finished=" +
(a.activity != null && a.activity.mFinished));
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);
}
if (stopProfiling) {
mProfiler.stopProfiling();
}
applyPendingProcessState();
return false;
}
}
@Override
public final void activityIdle(IBinder token, Configuration config,
boolean stopProfiling) {
final long origId = Binder.clearCallingIdentity();
try {
WindowProcessController proc = null;
synchronized (mGlobalLock) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack == null) {
return;
}
// 关键调用
final ActivityRecord r =
mStackSupervisor.activityIdleInternalLocked(token,
false, false, config);
if (r != null) {
proc = r.app;
}
if (stopProfiling && proc != null) {
proc.clearProfilerIfNeeded();
}
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
final ActivityRecord activityIdleInternalLocked(final IBinder token,
boolean fromTimeout, boolean processPausingActivities,
Configuration config) {
if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
ArrayList<ActivityRecord> finishes = null;
ArrayList<UserState> startingUsers = null;
int NS = 0;
int NF = 0;
boolean booting = false;
boolean activityRemoved = false;
ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
r.finishLaunchTickingLocked();
if (fromTimeout) {
reportActivityLaunchedLocked(fromTimeout, r, INVALID_DELAY,
-1 /* launchState */);
}
if (config != null) {
r.setLastReportedGlobalConfiguration(config);
}
r.idle = true;
if ((mService.isBooting() &&
mRootActivityContainer.allResumedActivitiesIdle())
|| fromTimeout) {
booting = checkFinishBootingLocked();
}
r.mRelaunchReason = RELAUNCH_REASON_NONE;
}
if (mRootActivityContainer.allResumedActivitiesIdle()) {
if (r != null) {
mService.scheduleAppGcsLocked();
}
if (mLaunchingActivityWakeLock.isHeld()) {
mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
if (VALIDATE_WAKE_LOCK_CALLER &&
Binder.getCallingUid() != Process.myUid()) {
throw new IllegalStateException(
"Calling must be system uid");
}
mLaunchingActivityWakeLock.release();
}
mRootActivityContainer.ensureActivitiesVisible(
null, 0, !PRESERVE_WINDOWS);
}
// Atomically retrieve all of the other things to do.
// 关键点:处理之前处于 stopping 状态的 Activity
final ArrayList<ActivityRecord> stops =
processStoppingActivitiesLocked(r,
true /* remove */, processPausingActivities);
NS = stops != null ? stops.size() : 0;
if ((NF = mFinishingActivities.size()) > 0) {
finishes = new ArrayList<>(mFinishingActivities);
mFinishingActivities.clear();
}
if (mStartingUsers.size() > 0) {
startingUsers = new ArrayList<>(mStartingUsers);
mStartingUsers.clear();
}
// Stop any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = 0; i < NS; i++) {
r = stops.get(i);
final ActivityStack stack = r.getActivityStack();
if (stack != null) {
if (r.finishing) {
// 关键调用
stack.finishCurrentActivityLocked(
r, ActivityStack.FINISH_IMMEDIATELY, false,
"activityIdleInternalLocked");
} else {
stack.stopActivityLocked(r);
}
}
}
// Finish any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = 0; i < NF; i++) {
r = finishes.get(i);
final ActivityStack stack = r.getActivityStack();
if (stack != null) {
activityRemoved |= stack.destroyActivityLocked(
r, true, "finish-idle");
}
}
......
mService.mH.post(() -> mService.mAmInternal.trimApplications());
//dump();
//mWindowManager.dump();
if (activityRemoved) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return r;
}
activityIdleInternalLocked() 函数内部依次处理 stop、finish 状态的 Activity,最后会执行到 AMS 的 trimApplications(),在该函数中执行内存回收。在这个方法中的关键就是对 stopping 状态的 Activity 的处理。
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
int mode, boolean oomAdj, String reason) {
final ActivityDisplay display = getDisplay();
// 获取下一个 Activity
final ActivityRecord next =
display.topRunningActivity(true);
final boolean isFloating =
r.getConfiguration().windowConfiguration.tasksAreFloating();
// 如果 mode 为 FINISH_AFTER_VISIBLE 且下一个 Activity 不可见(默认即为此),
// 则先将当前 Activity 添加到 stopping 列表,并将其状态设置为 STOPPING
// 等下一个 Activity 可见后再 finish 当前 Activity
if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
&& next != null && !next.nowVisible && !isFloating) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
// 添加到 stopping 列表.
addToStopping(r, false /* scheduleIdle */,
false /* idleDelayed */, "finishCurrentActivityLocked");
}
// Activity 状态设置为 STOPPING
r.setState(STOPPING, "finishCurrentActivityLocked");
if (oomAdj) {
mService.updateOomAdj();
}
return r;
}
// make sure the record is cleaned out of other places.
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
// 获取当前状态
final ActivityState prevState = r.getState();
// Activity 状态设置为 FINISHING
r.setState(FINISHING, "finishCurrentActivityLocked");
// 如果没有要显示的下一个 Activity 且当前显示的栈中包含 Home 栈,
// 则先等 HomeActivity 恢复之后
// 再销毁当前 Activity 这样做的目的是避免出现临时黑屏
final boolean noRunningStack = next == null &&
display.topRunningActivity() == null &&
display.getHomeStack() == null;
final boolean noFocusedStack = r.getActivityStack() !=
display.getFocusedStack();
final boolean finishingInNonFocusedStackOrNoRunning = mode ==
FINISH_AFTER_VISIBLE &&
prevState == PAUSED && (noFocusedStack || noRunningStack);
if (mode == FINISH_IMMEDIATELY
|| (prevState == PAUSED && (mode == FINISH_AFTER_PAUSE ||
inPinnedWindowingMode()))
|| finishingInNonFocusedStackOrNoRunning
|| prevState == STOPPING
|| prevState == STOPPED
|| prevState == ActivityState.INITIALIZING) {
// 设置 finishing=true
r.makeFinishingLocked();
// 关键点:销毁当前 Activity
boolean activityRemoved = destroyActivityLocked(
r, true, "finish-imm:" + reason);
if (finishingInNonFocusedStackOrNoRunning) {
mRootActivityContainer.ensureVisibilityAndConfig(
next, mDisplayId,
false /* markFrozenIfConfigChanged */, true);
}
if (activityRemoved) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return activityRemoved ? null : r;
}
if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
mStackSupervisor.mFinishingActivities.add(r);
r.resumeKeyDispatchingLocked();
mRootActivityContainer.resumeFocusedStacksTopActivities();
if (r.isState(RESUMED) && mPausingActivity != null) {
startPausingLocked(false /* userLeaving */, false,
next /* resuming */, false /* dontWait */);
}
return r;
}
这里不会想之前执行 addToStopping 方法了,而是执行 destroyActivityLocked 操作.
final boolean destroyActivityLocked(ActivityRecord r,
boolean removeFromApp, String reason) {
if (r.isState(DESTROYING, DESTROYED)) {
return false;
}
boolean removedFromHistory = false;
cleanUpActivityLocked(r, false, false);
final boolean hadApp = r.hasProcess();
if (hadApp) {
if (removeFromApp) {
r.app.removeActivity(r);
if (!r.app.hasActivities()) {
mService.clearHeavyWeightProcessIfEquals(r.app);
}
if (!r.app.hasActivities()) {
r.app.updateProcessInfo(true,
false, true /* updateOomAdj */);
}
}
boolean skipDestroy = false;
// 关键调用:将最终状态设置为 DestroyActivityItem
mService.getLifecycleManager().scheduleTransaction(
r.app.getThread(), r.appToken,
DestroyActivityItem.obtain(r.finishing, r.configChangeFlags));
r.nowVisible = false;
if (r.finishing && !skipDestroy) {
// Activity 状态设置为 DESTROYING
r.setState(DESTROYING,
"destroyActivityLocked. finishing and not skipping destroy");
Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
} else {
r.setState(DESTROYED,
"destroyActivityLocked. not finishing or skipping destroy");
r.app = null;
}
} else {
// remove this record from the history.
if (r.finishing) {
removeActivityFromHistoryLocked(r, reason + " hadNoApp");
removedFromHistory = true;
} else {
r.setState(DESTROYED,
"destroyActivityLocked. not finishing and had no app");
r.app = null;
}
}
r.configChangeFlags = 0;
return removedFromHistory;
}
可以看到,最终是通过执行 DestroyActivityItem 来完成 onStop 和 onDestroy 生命周期的调用的,至于为什么会执行 onStop 生命周期,请同学们参考 深入理解 ClientLifecycleManager 机制 中对 cycleToPath 的分析。至于详细的 onStop 和 onDestroy 的调用,之前已经有介绍,在此不再赘述。
至此 Activity 的 finish 流程基本介绍完毕,如有问题,欢迎留言沟通,整个调用流程图如下:
参考文章:
http://mouxuejie.com/blog/2020-03-22/finish-activity/
https://zhuanlan.zhihu.com/p/156939189