Activity退出流程(基于AOSP 13)
Activity退出流程
1、onPause
1.1 服务侧发起Pause
在Activity启动流程中,我们知道会调用startPausing方法来触发栈顶的activity进入onPause状态。
// frameworks\base\services\core\java\com\android\server\wm\TaskFragment.java
boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
String reason) {
...
if (prev.attachedToProcess()) {
.....
// 调用pause周期
schedulePauseActivity(prev, userLeaving, pauseImmediately, reason);
}
if (mPausingActivity != null) {
// 启动定时
prev.schedulePauseTimeout();
// 未设置的准备,因为我们现在需要等到完成此暂停。
mTransitionController.setReady(this, false /* ready */);
return true;
}
}
schedulePauseActivity 方法主要发送对应的ActivityLifecycleItem,即PauseActivityItem给到客户端。
void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
boolean pauseImmediately, String reason) {
try {
// 发送Pause的事务
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
....
}
}
1.2 应用侧执行Pause
通过Activity生命周期流程中分析,知道最终会调用事务的execute
// frameworks\base\core\java\android\app\servertransaction\PauseActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
// 调用ActivityThread的handlePauseActivity
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
}
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
// 将当前的周期状态告知AMS
ActivityClient.getInstance().activityPaused(token);
}
// frameworks\base\core\java\android\app\ActivityThread.java
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(r, finished, reason, pendingActions);
....
}
}
接着调用performPauseActivity
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
PendingTransactionActions pendingActions) {
....
final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
if (shouldSaveState) {
// android 3之前会在on Pause之前调用onSaveInstanceState周期
callActivityOnSaveInstanceState(r);
}
performPauseActivityIfNeeded(r, reason);
.....
return shouldSaveState ? r.state : null;
}
performPauseActivityIfNeeded
中调用callActivityOnPause
方法
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
....
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
} catch (SuperNotCalledException e) {
}
.....
}
Instrumentation
的callActivityOnPause
方法是直接掉用activity的performPause
1.3 回调通知AMS pause完毕
在PauseActivityItem的postExecute 方法中,会通过IActivityClientController 接口通知到ActivityClientController
ActivityClientController
中就是调用ActivityRecord
的activityPaused()
方法
//frameworks\base\services\core\java\com\android\server\wm\ActivityClientController.java
public void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
r.activityPaused(false);
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
Binder.restoreCallingIdentity(origId);
}
ActivityRecord
的activityPaused()
中,主要是取消pause的超时并通知TaskFragment更新ActivityRecord的生命周期状态。
// frameworks\base\services\core\java\com\android\server\wm\ActivityRecord.java
void activityPaused(boolean timeout) {
ProtoLog.v(WM_DEBUG_STATES, "Activity paused: token=%s, timeout=%b", token,
timeout);
final TaskFragment taskFragment = getTaskFragment();
if (taskFragment != null) {
// 移除Pause的超时
removePauseTimeout();
final ActivityRecord pausingActivity = taskFragment.getPausingActivity();
if (pausingActivity == this) {
ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
(timeout ? "(due to timeout)" : " (pause complete)"));
mAtmService.deferWindowLayout();
try {
// 通知taskFragment,完成pause周期
taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
} finally {
mAtmService.continueWindowLayout();
}
return;
} else {
....
if (isState(PAUSING)) {
setState(PAUSED, "activityPausedLocked"); // 更新ActivityRecord 生命周期状态
if (finishing) {
ProtoLog.v(WM_DEBUG_STATES,
"Executing finish of failed to pause activity: %s", this);
completeFinishing("activityPausedLocked");
}
}
}
}
mDisplayContent.handleActivitySizeCompatModeIfNeeded(this);
mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
}
// frameworks\base\services\core\java\com\android\server\wm\TaskFragment.java
void completePause(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (prev != null) {
if (prev.hasProcess()) {
if (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) {
prev.setDeferHidingClient(false);
// 添加到stopping状态
prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */,
"completePauseLocked");
}
}
}
if (resumeNext) { // 需要启动下一个activity
final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (topRootTask != null && !topRootTask.shouldSleepOrShutDownActivities()) {
// 通知启动下一个activity
mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev,
null /* targetOptions */);
}
}
}
2、onStop
2.1 应用
在新activity走完onResume后,会调用到上个activity的onStop。
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
boolean isForward, String reason) {
// 准备调用Resume周期
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
....
Looper.myQueue().addIdleHandler(new Idler());
}
在上一个Activity handleResumeActivity
的最后,会注册一个Idler接口,该接口会在handler空闲的时候调用
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
if (a != null) {
mNewActivities = null;
final ActivityClient ac = ActivityClient.getInstance();
ActivityClientRecord prev;
do {
....
if (a.activity != null && !a.activity.mFinished) {
// 调用ActivityClientController 的activityIdle
ac.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
applyPendingProcessState();
return false;
}
}
2.2 AMS 发起stop
轻车熟路找到ActivityClientController
中
//frameworks\base\services\core\java\com\android\server\wm\ActivityClientController.java
public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
final long origId = Binder.clearCallingIdentity();
....
try {
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle");
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r == null) {
return;
}
mTaskSupervisor.activityIdleInternal(r, false /* fromTimeout */,
false /* processPausingActivities */, config);
if (stopProfiling && r.hasProcess()) {
r.app.clearProfilerIfNeeded();
}
}
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Binder.restoreCallingIdentity(origId);
}
}
调用到ActivityTaskSupervisor的activityIdleInternal
// frameworks\base\services\core\java\com\android\server\wm\ActivityTaskSupervisor.java
void activityIdleInternal(ActivityRecord r, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
if (r != null) {
....
// 移除超时的消息
mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
....
r.mRelaunchReason = RELAUNCH_REASON_NONE;
}
....
// 调用上一个activity的onStop
processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
}
processStoppingAndFinishingActivities方法用于处理Activity停止或销毁。这应该是闲置或绘制时调用恢复活动。
private void processStoppingAndFinishingActivities(ActivityRecord launchedActivity,
boolean processPausingActivities, String reason) {
....
final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
for (int i = 0; i < numReadyStops; i++) {
final ActivityRecord r = readyToStopActivities.get(i);
if (r.isInHistory()) {
if (r.finishing) {
// 被标记为finishing,则调用销毁的周期
r.destroyIfPossible(reason);
} else {
// 调用onStop的周期。
r.stopIfPossible();
}
}
}
....
}
我们先看stopIfPossible
方法
// frameworks\base\services\core\java\com\android\server\wm\ActivityRecord.java
void stopIfPossible() {
final Task rootTask = getRootTask();
try {
stopped = false;
// 向app端发送StopActivityItem 周期
setState(STOPPING, "stopIfPossible");
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token,
StopActivityItem.obtain(configChangeFlags));
// 添加超时的计时
mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT);
} catch (Exception e) {
}
.....
}