前四篇文章通过启动一个Activity,把AMS的启动流程分析了一遍。虽然说只是启动流程,但是也包含了大多数的Activity的生命周期方法,所以想onCreate,onStart,onResume,onPause等等方法我们都已经看到了。剩下还有个onDestory的销毁方法我们还没说过,所以这篇文章主要说一下onDestory的方法。
我们都知道销毁一个Activity的方法是调用finish,我们就从Activity的finish开始看起:
```java
public void finish() {
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
private void finish(int finishTask) {
if (mParent == null) {
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (false) Log.v(TAG, "Finishing self: token=" + mToken);
try {
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
if (ActivityManager.getService()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
}
```
这里我们看到一般调用无参的finish方法,会自动调用有一个参数的finish方法,传入的参数是DONT_FINISH_TASK_WITH_ACTIVITY,当一个activity是一个tqask的root activity的时候,不需要finish这个task,这个后面到AMS时候可以看到会判断这个参数,这里最终会调用到AMS的finishActivity方法。这里通过ActivityManager的代理类跨进程调用是通过binder,具体实现是AIDL,具体之前已经有说过了,这里就不展开了,我们直接到AMS中去看这个方法:
```java
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
// Refuse possible leaked file descriptors
if (resultData != null && resultData.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized(this) {
// 获取finish的Activity
ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return true;
}
..............
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)) {
// 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.
res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
if (!res) {
Slog.i(TAG, "Removing task failed to finish activity");
}
} else {
res = tr.getStack().requestFinishActivityLocked(token, resultCode,
resultData, "app-request", true);
if (!res) {
Slog.i(TAG, "Failed to finish by app-request");
}
}
return res;
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
```
这个方法最后我们看到判断了finishTask这个变量,这个变量就是开始我们说的调用finish无参构造函数时候自动传入的参数,那时候传入的是DONT_FINISH_TASK_WITH_ACTIVITY,表示当activity是task的root activity的时候,不需要finish task,所以这里走的是后面的这个分支,调用的是Activity stack的requestFinishActivityLocked方法,我们跟进去看一下:
```java
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Intent resultData, String reason, boolean oomAdj) {
// 通过IApplicationToken.Stub获取对应的ActivityRecord
ActivityRecord r = isInStackLocked(token);
if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
"Finishing activity token=" + token + " r="
+ ", result=" + resultCode + ", data=" + resultData
+ ", reason=" + reason);
if (r == null) {
return false;
}
// 继续调用finish
finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
return true;
}
```
这里首先获得ActivityRecord,如果非空的话,继续调用finishActivityLocked方法:
```java
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj) {
return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
}
```
然后再继续调用finishActivityLocked:
```java
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj, boolean pauseImmediately) {
if (r.finishing) { // 如果已经在finish中了,return
Slog.w(TAG, "Duplicate finish request for " + r);
return false;
}
mWindowManager.deferSurfaceLayout();
try {
// 把Activity的finish标签置为true
r.makeFinishingLocked();
// 获取该Activity的task
final TaskRecord task = r.getTask();
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
r.userId, System.identityHashCode(r),
task.taskId, r.shortComponentName, reason);
// 获取这个task中所有的Activity集合
final ArrayList<ActivityRecord> activities = task.mActivities;
// 获取需要finish的Activity在集合中的下标
final int index = activities.indexOf(r);
if (index < (activities.size() - 1)) {
// 调整这个task中的头Activity标志
task.setFrontOfTask();
if ((r.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.
ActivityRecord next = activities.get(index+1);
next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
}
}
// 停止事件分发
r.pauseKeyDispatchingLocked();
// 调整ActivityStack
adjustFocusedActivityStackLocked(r, "finishActivity");
// 把要回复的数据设置给要回复的Activity
finishActivityResultsLocked(r, resultCode, resultData);
final boolean endTask = index <= 0;
final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
if (mResumedActivity == r) { // 如果当前要finish的这个Activity是前台的,先要调用pause方法
if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare close transition: finishing " + r);
if (endTask) {
mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(
task.taskId);
}
mWindowManager.prepareAppTransition(transit, false);
// Tell window manager to prepare for this one to be removed.
r.setVisibility(false);
if (mPausingActivity == null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"finish() => pause with userLeaving=false");
// 调用pause方法
startPausingLocked(false, false, null, pauseImmediately);
}
if (endTask) {
mStackSupervisor.removeLockedTaskLocked(task);
}
} else if (r.state != ActivityState.PAUSING) { // 非正在pause状态
// If the activity is PAUSING, we will complete the finish once
// it is done pausing; else we can just directly finish it here.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
if (r.visible) {
prepareActivityHideTransitionAnimation(r, transit);
}
// 如果这个要删除的Activity,还是要显示的状态,可能没有完全停止,那么我们等他完全停止后再finfish
// 一旦已经pause好了,可以直接finish了
final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE
: FINISH_AFTER_PAUSE;
// 调用finish方法
final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj)
== null;
................
if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
for (ActivityRecord taskOverlay : task.mActivities) {
if (!taskOverlay.mTaskOverlay) {
continue;
}
prepareActivityHideTransitionAnimation(taskOverlay, transit);
}
}
return removedActivity;
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
}
return false;
} finally {
mWindowManager.continueSurfaceLayout();
}
}
```
如果这个Activity正在finish的话,就退出。否则会调用makeFinishingLocked方法,把finishing标记置为true,方法如下:
```java
void makeFinishingLocked() {
if (!finishing) {
final ActivityStack stack = getStack();
if (stack != null && this == stack.getVisibleBehindActivity()) {
// A finishing activity should not remain as visible in the background
mStackSupervisor.requestVisibleBehindLocked(this, false);
}
finishing = true;
if (stopped) {
clearOptionsLocked();
}
if (service != null) {
service.mTaskChangeNotificationController.notifyTaskStackChanged();
}
}
}
```
可以看到这个方法首先确认下这个被finish是否是个后台可见的Actvity,比如一个Activity的上面被另一个半透明的Activity盖住了,那么他就是后台可见的Activity,既然马上要finish了,虽然是后台可见,那么也是不可以的,所以要处理下,这里调用requestVisibleBehindLocked方法:
```java
boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
final ActivityStack stack = r.getStack();
if (stack == null) {
if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
"requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
return false;
}
// 这些个ActivityStack本来就是不可以在后台可见的,所以return
if (visible && !StackId.activitiesCanRequestVisibleBehind(stack.mStackId)) {
if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: r=" + r
+ " visible=" + visible + " stackId=" + stack.mStackId
+ " can't contain visible behind activities");
return false;
}
// 当前这个stack是否有后台可见的activity
final boolean isVisible = stack.hasVisibleBehindActivity();
if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
"requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
// 当前焦点顶部显示的activity
final ActivityRecord top = topRunningActivityLocked();
if (top == null || top == r || (visible == isVisible)) {
if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
stack.setVisibleBehindActivity(visible ? r : null);
return true;
}
// A non-top activity is reporting a visibility change.
if (visible && top.fullscreen) {
// Let the caller know that it can't be seen.
if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
"requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
+ " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
+ top.app.thread);
return false;
} else if (!visible && stack.getVisibleBehindActivity() != r) { // 当前后台可见的不是传入的这个Activiry,没必要处理了
// Only the activity set as currently visible behind should actively reset its
// visible behind state.
if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
"requestVisibleBehind: returning visible=" + visible
+ " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
+ " r=" + r);
return false;
}
// 把ActivityStack的behind activity设置为null
stack.setVisibleBehindActivity(visible ? r : null);
if (!visible) {
// If there is a translucent home activity, we need to force it stop being translucent,
// because we can't depend on the application to necessarily perform that operation.
// Check out b/14469711 for details.
final ActivityRecord next = stack.findNextTranslucentActivity(r);
if (next != null && next.isHomeActivity()) {
mService.convertFromTranslucent(next.appToken);
}
}
if (top.app != null && top.app.thread != null) {
// Notify the top app of the change.
try {
top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
} catch (RemoteException e) {
}
}
return true;
}
```
现在我们要finish的这个Actvity,如果是处于一个后台但是可见的activity,那么我们可以从他所在的ActivityStack的mVisibleBehindActivity变量中看一看,是不是这个activity。mVisibleBehindActivity是保存着这个ActivityStack中当前的后台可见的Activity。这个方法做了一些检查,比如这个ActivityStack本来就不是一个有后台可见Activity的话,那么就直接返回。如果没有什么异常的话,会调用setVisibleBehindActivity方法把mVisibleBehindActivity变量置空。最后还会通过跨进程通信调用对方进程的scheduleBackgroundVisibleBehindChanged方法,这个方法最终会调用到Activity的onBackgroundVisibleBehindChanged方法,默认这个方法实现是空,用户可以重写这个方法,这个就不多说了,回到makeFinishingLocked,后面就把finishing置为true,表示这个Activity现在是处于finish的过程中。好了,我们继续回到finishActivityLocked方法。
由于我们现在是要finish一个activity,所以如果这个activity当前正好是他所在的taskRecord中的root activity,那么就要调整下,把他后面的设置为root activity。我们看下taskRecord的setFrontOfTask方法:
```java
// 把第1个非finish的Activity设置为fontOfTask
// 如果只有1个正在finish的Activity,那就把他的frontOfTask置为true
final void setFrontOfTask() {
boolean foundFront = false;
final int numActivities = mActivities.size();
for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
final ActivityRecord r = mActivities.get(activityNdx);
if (foundFront || r.finishing) {
r.frontOfTask = false;
} else {
r.frontOfTask = true;
// Set frontOfTask false for every following activity.
foundFront = true;
}
}
if (!foundFront && numActivities > 0) {
// All activities of this task are finishing. As we ought to have a frontOfTask
// activity, make the bottom activity front.
mActivities.get(0).frontOfTask = true;
}
}
```
这个方法遍历taskRecord的mActivities集合,从前往后找到一个不是finish状态的activityRecord把他的frontOfTask变量置为true,即他是root activity了。如果所有的Activity都处于finish状态,那么就设置第一个Activity位root activity。
接着往后看,之后停止事件分发处理后,由于我们现在是finish一个Activity,每个Activity是在taskRecord中的,而taskRecord是在一个ActivityStack中的,所以如果finish了一个Activity后,有可能焦点ActivityStack就会改变了,所以这里需要重新更新下焦点的ActivityStack,我们看下调用方法adjustFocusedActivityStackLocked:
```java
// 既然这个Activity要finish掉了,那么调整下焦点stack
private void adjustFocusedActivityStackLocked(ActivityRecord r, String reason) {
// 如果这个要finish的Activity所在的stack不是聚焦的,return
// 或者当前这个stack的resume的Activity不是将要删除的这个Activity,那么也return
// 以前两种情况都不需要调整stack
if (!mStackSupervisor.isFocusedStack(this) ||
((mResumedActivity != r) && (mResumedActivity != null))) {
return;
}
// 获取这个stack的后台的Activity
final ActivityRecord next = topRunningActivityLocked();
final String myReason = reason + " adjustFocus";
if (next != r) { // 如果顶部的Activity不是要删除的Activity
// 对应docked,pinned等模式的stack,由于顶部的Activity不是要删除的并且存在,所以也不做调整
if (next != null && StackId.keepFocusInStackIfPossible(mStackId) && isFocusable()) {
// For freeform, docked, and pinned stacks we always keep the focus within the
// stack as long as there is a running activity.
return;
} else {
// Task is not guaranteed to be non-null. For example, destroying the
// {@link ActivityRecord} will disassociate the task from the activity.
// 获取删除的Activiy所在的task
final TaskRecord task = r.getTask();
if (task == null) {
throw new IllegalStateException("activity no longer associated with task:" + r);
}
final boolean isAssistantOrOverAssistant = task.getStack().isAssistantStack() ||
task.isOverAssistantStack();
// 如果这个要finish的Activity所在的task就只有他一个,或者除了他其他没有可以正常显示的Activity了
if (r.frontOfTask && isATopFinishingTask(task)
&& (task.isOverHomeStack() || isAssistantOrOverAssistant)) {
// For non-fullscreen or assistant stack, we want to move the focus to the next
// visible stack to prevent the home screen from moving to the top and obscuring
// other visible stacks.
// 如果是一个非全屏显示的,又因为进入到这里现在要finish的task没有东西可以显示了
// 那么就调用adjustFocusToNextFocusableStackLocked方法来寻找一个合适的stack来显示到前台
if ((!mFullscreen || isAssistantOrOverAssistant)
&& adjustFocusToNextFocusableStackLocked(myReason)) {
return;
}
// Move the home stack to the top if this stack is fullscreen or there is no
// other visible stack.
// 到这里说明finish的这个task是home的,但是要从home的task中找一个放到前台
if (task.isOverHomeStack() &&
mStackSupervisor.moveHomeStackTaskToTop(myReason)) {
// Activity focus was already adjusted. Nothing else to do...
return;
}
}
}
}
// 到这里就把当前非前台的activity显示到最前面
mStackSupervisor.moveFocusableActivityStackToFrontLocked(
mStackSupervisor.topRunningActivityLocked(), myReason);
}
```
这个方法开始进行了盘点,如果非焦点ActivityStack就退出了,从非焦点ActvityStack中删除一个Activity自然不需要调整焦点ActivityStack。如果是焦点ActivityStack,同时是非resumedActivity,自然也不需要调整焦点ActivityStack。所以能进入下面执行的话,只能是焦点ActivityStack并且是resumedActivity才会进入下面执行。
接着这个方法首先取出非前台的Activity,然后比较下和要删除的Activity是否一样,如果不一样,会判断下这个ActivityStack类型,有些类型的ActivityStack只要里面存在Activty就不需要改变焦点,比如freedom,docked,pinned等模式。如果非这些类型的话,再次判断,如果这个删除的Activity在他的task中就只有他一个,并且是一个非全屏的Activity,那么会调用adjustFocusToNextFocusableStackLocked来选择一个合适的stack作为焦点ActivityStack,如果这个task是主界面的,那么会选择主界面的ActivityStack作为主界面。
最后如果以上条件都没有触发的话,由于进入到这里只可能是焦点ActivityStack,并且删除的这个只可能是resumedActivity。所以最后调用moveFocusableActivityStackToFrontLocked,从当前ActivityStack,即焦点ActivityStack中选择一个非前台的Activity来显示。这样焦点ActivityStack就更新了。好了,回到finishActivityLocked方法。
之后由于这个Activity要finish了,所以他如果有要回复的数据,要保存一下,这里调用finishActivityResultsLocked方法:
```java
private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
// send the result
// 获取要回复的Activity
ActivityRecord resultTo = r.resultTo;
if (resultTo != null) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo
+ " who=" + r.resultWho + " req=" + r.requestCode
+ " res=" + resultCode + " data=" + resultData);
if (resultTo.userId != r.userId) {
if (resultData != null) {
resultData.prepareToLeaveUser(r.userId);
}
}
if (r.info.applicationInfo.uid > 0) {
mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
resultTo.packageName, resultData,
resultTo.getUriPermissionsLocked(), resultTo.userId);
}
// 把回复数据设置到要回复的Activity中
resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
resultData);
r.resultTo = null;
}
else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
// 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.
r.results = null;
r.pendingResults = null;
r.newIntents = null;
r.icicle = null;
}
```
这个方法中调用addResultLocked方法,把回复的数据会保存在ActivityRecord的results集合中,这个集合中保存了所有需要回复的数据对象。然后把要finish的这个ActivityRecord回复数据置空就可以了。
在回到finishActivityLocked方法,如果当前Activity是前台显示的Activity,并且当前没有正在停止的Activity,那么会调用startPausingLocked方法先停止这个Activity。如果不是前台显示的Activity,并且不是停止状态那么会调用finishCurrentActivityLocked方法。这2个方法最后会殊途同归,我们先看前面startPausingLocked这个方法。
# 客户端Pause方法调用
startPausingLocked这个方法前面也有过分析,但是分析到跨进程调用到客户端的时候就没有继续分析下去了,所以现在我们在继续从调用到客户端的地方开始分析下去。跨进程后会调用到客户端的schedulePauseActivity方法,我们从这里开始分析:
```java
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
+ " operation received seq: " + seq);
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
```
这里没啥好说的,发送消息给Handler,这里由于是finish的流程,会发送PAUSE_ACTIVITY_FINISHING消息,另外这里最后一个参数dontReport,从前面传过来的是false,表示停止完后需要要AMS回复:
```java
case PAUSE_ACTIVITY_FINISHING: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
```
继续调用handlePauseActivity方法:
```java
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
ActivityClientRecord r = mActivities.get(token);
if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
return;
}
if (r != null) {
//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
// 是否是用户主动停止
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
// Tell the activity manager we have paused.
// 向AMS回复消息
if (!dontReport) {
try {
ActivityManager.getService().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
```
这个方法里面有3个步骤。第一个步骤,如果是用户操作主动停止的话,会调用performUserLeavingActivity方法。第二个步骤就是停止Actvity的方法performPauseActivity。第三个步骤,停止的执行完毕后,向AMS回复消息会回调到AMS的activityPaused方法。我们先看第一个performUserLeavingActivity方法。
```java
final void performUserLeavingActivity(ActivityClientRecord r) {
mInstrumentation.callActivityOnUserLeaving(r.activity);
}
```
继续调用Instrumentation的callActivityOnUserLeaving方法:
```java
public void callActivityOnUserLeaving(Activity activity) {
activity.performUserLeaving();
}
```
再调用到Activity的performUserLeaving方法:
```java
final void performUserLeaving() {
onUserInteraction();
onUserLeaveHint();
}
```
这里2个Activity的方法onUserInteraction和onUserLeaveHint默认都是空,所以需要用户有需要的话可以重写,一般这个我们平时开发中用的也不多,这里我们知道当停止的时候有这2个方法会触发就可以。回到前面方法,看具体停止的方法performPauseActivity:
```java
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState, String reason) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
}
```
这里根据要停止Activity的token,即在AMS中保存的ActivityRecord,取出客户端的ActivityClientRecord,继续调用performPauseActivity方法:
```java
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState, String reason) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
}
```
这里继续调用performPauseActivity方法:
```java
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState, String reason) {
if (r.paused) {
if (r.activity.mFinished) {
// If we are finishing, we won't call onResume() in certain cases.
// So here we likewise don't want to call onPause() if the activity
// isn't resumed.
return null;
}
RuntimeException e = new RuntimeException(
"Performing pause of activity that is not resumed: "
+ r.intent.getComponent().toShortString());
Slog.e(TAG, e.getMessage(), e);
}
if (finished) {
r.activity.mFinished = true;
}
// Next have the activity save its current state and managed dialogs...
if (!r.activity.mFinished && saveState) {
callCallActivityOnSaveInstanceState(r);
}
performPauseActivityIfNeeded(r, reason);
// Notify any outstanding on paused listeners
ArrayList<OnActivityPausedListener> listeners;
synchronized (mOnPauseListeners) {
listeners = mOnPauseListeners.remove(r.activity);
}
int size = (listeners != null ? listeners.size() : 0);
for (int i = 0; i < size; i++) {
listeners.get(i).onPaused(r.activity);
}
return !r.activity.mFinished && saveState ? r.state : null;
}
```
这个方法首先判断是否已经处于pause和finish状态了,如果已经处于了,就return,否则继续调用performPauseActivityIfNeeded方法:
```java
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
if (r.paused) { // 已经pause了,return
// You are already paused silly...
return;
}
try {
r.activity.mCalled = false;
// 调用onPause方法
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName(), reason);
if (!r.activity.mCalled) {
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
+ " did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException("Unable to pause activity "
+ safeToComponentShortString(r.intent) + ": " + e.toString(), e);
}
}
r.paused = true;
}
```
这个方法逻辑也比较清楚,调用Instrumentation的callActivityOnPause方法:
```java
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
onPause();
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}
```
最后会调到Activity的performPause方法,里面会回调Activity的onPause方法,这个大家也比较熟悉了。好了,我们再回到handlePauseActivity方法。
# pause执行完毕通知AMS
最后会再次执行activityPaused方法通知AMS,回到AMS的activityPaused方法:
```java
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
```
回到AMS后,这里取出Activity所在的ActivityStack,调用activityPausedLocked:
```java
final void activityPausedLocked(IBinder token, boolean timeout) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
"Activity paused: token=" + token + ", timeout=" + timeout);
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
mService.mWindowManager.deferSurfaceLayout();
try {
completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
return;
} else {
EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
r.userId, System.identityHashCode(r), r.shortComponentName,
mPausingActivity != null
? mPausingActivity.shortComponentName : "(none)");
if (r.state == ActivityState.PAUSING) {
r.state = ActivityState.PAUSED;
if (r.finishing) {
if (DEBUG_PAUSE) Slog.v(TAG,
"Executing finish of failed to pause activity: " + r);
finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
}
}
}
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
```
这里取得要finish的ActivityRecord后,如果不为空,会调用completePauseLocked方法。这个方法在第三篇的分析中已经有过分析了,那时候还是在分析启动一个Activity的过程,我们这里主要看下和finish有关的:
```java
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
// 把mPausingActivity赋值给prev
ActivityRecord prev = mPausingActivity;
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
//
if (prev != null) {
final boolean wasStopping = prev.state == STOPPING;
prev.state = ActivityState.PAUSED;
if (prev.finishing) { // 这个activity准备finish
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
}
...................
}
```
前面我们在分析makeFinishingLocked方法的时候已经把ActivityRecord的finishing值设置为true了,所以这里看到如果当前这个已经停止的Activity已经被标记为finish了,那么会调用finishCurrentActivityLocked方法。这个方法前面我们在finishActivityLocked方法中也看到过,如果当前要finish的Activity不是前台的Activity,也会调用这个方法,现在我们就跟进这个方法去看:
```java
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
// First things first: 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.
// 获取当前顶部正在运行(非前台显示)的Activity
final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
// 如果这个Activity还是可见状态,那么先把他放入
if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
&& next != null && !next.nowVisible) {
// 如果stop集合中没有这个Activity,加入之
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
// 同时会根据情况触发onStop或者finish的执行
addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */);
}
if (DEBUG_STATES) Slog.v(TAG_STATES,
"Moving to STOPPING: "+ r + " (finish requested)");
// 把这个Activity的状态置为stop
r.state = STOPPING;
if (oomAdj) {
mService.updateOomAdjLocked();
}
return r;
}
// 走到这里说明准备要真的finish了,下面把之前加入了一些带删除的集合中移除他
// make sure the record is cleaned out of other places.
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(r);
// 如果当前resume是他的有,把他置空
if (mResumedActivity == r) {
mResumedActivity = null;
}
// 保留一下之前的状态
final ActivityState prevState = r.state;
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
// 最新状态改为finish
r.state = ActivityState.FINISHING;
final boolean finishingActivityInNonFocusedStack
= r.getStack() != mStackSupervisor.getFocusedStack()
&& prevState == ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE;
if (mode == FINISH_IMMEDIATELY
|| (prevState == ActivityState.PAUSED
&& (mode == FINISH_AFTER_PAUSE || mStackId == PINNED_STACK_ID))
|| finishingActivityInNonFocusedStack
|| prevState == STOPPING
|| prevState == STOPPED
|| prevState == ActivityState.INITIALIZING) {
// 设置下正在删除的标志
r.makeFinishingLocked();
// 开始调用destory方法
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");
if (finishingActivityInNonFocusedStack) {
// Finishing activity that was in paused state and it was in not currently focused
// stack, need to make something visible in its place.
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
if (activityRemoved) { // 删除成功,显示后面的焦点界面
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
"destroyActivityLocked: finishCurrentActivityLocked r=" + r +
" destroy returned removed=" + activityRemoved);
return activityRemoved ? null : r;
}
// Need to go through the full pause cycle to get this
// activity into the stopped state and then finish it.
if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
// 走到这里说明先把个Activity加入到带finish的集合中,后面会会finish
// 加入finish集合
mStackSupervisor.mFinishingActivities.add(r);
r.resumeKeyDispatchingLocked();
// 显示下一个焦点界面
mStackSupervisor.resumeFocusedStackTopActivityLocked();
return r;
}
```
这个方法可能是立即执行destory一个activity的操作,也有可能会延迟执行,比如遇到一个当前可能正在等待被显示,或者正在stopping的Activity,总之来说目前还不适合finish,所以这些Activity会被暂时加入到一个stops或者finishes的集合中,等着下一个界面resume后会被执行。记得我们在分析启动过程的时候,在handleResumeActivity方法中会给Handler发送一个addIdleHandler的消息吗,这些加入stops和finishes的对象会在Handler处理这些消息的时候执行,我们稍后会看下如果处理stops和finishes集合的,在这之前我们这里先看下怎么destroy一个Activity的,上面的方法中会调用destroyActivityLocked来销毁一个Activity:
```java
final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(TAG_SWITCH,
"Removing activity from " + reason + ": token=" + r
+ ", app=" + (r.app != null ? r.app.processName : "(null)"));
EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
r.userId, System.identityHashCode(r),
r.getTask().taskId, r.shortComponentName, reason);
boolean removedFromHistory = false;
// 清理一些带执行集合
cleanUpActivityLocked(r, false, false);
final boolean hadApp = r.app != null;
if (hadApp) {
if (removeFromApp) {
r.app.activities.remove(r); // 从这个进程中移除这个Activity
if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
mService.mHeavyWeightProcess = null;
mService.mHandler.sendEmptyMessage(
ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
}
if (r.app.activities.isEmpty()) {
// Update any services we are bound to that might care about whether
// their client may have activities.
mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
// No longer have activities, so update LRU list and oom adj.
mService.updateLruProcessLocked(r.app, false, null);
mService.updateOomAdjLocked();
}
}
boolean skipDestroy = false;
try {
if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r);
// 执行onDestory
r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
r.configChangeFlags);
} catch (Exception e) {
// We can just ignore exceptions here... if the process
// has crashed, our death notification will clean things
// up.
//Slog.w(TAG, "Exception thrown during finish", e);
if (r.finishing) {
removeActivityFromHistoryLocked(r, reason + " exceptionInScheduleDestroy");
removedFromHistory = true;
skipDestroy = true;
}
}
r.nowVisible = false;
if (r.finishing && !skipDestroy) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYING: " + r
+ " (destroy requested)");
r.state = ActivityState.DESTROYING;
// 这里会发生一个handle超时处理,如果ondestory没有在规定时间内返回取消这个handle任务的话,这里就会先执行
Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
} else {
if (DEBUG_STATES) Slog.v(TAG_STATES,
"Moving to DESTROYED: " + r + " (destroy skipped)");
r.state = ActivityState.DESTROYED;
if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
r.app = null;
}
} else {
// remove this record from the history.
// 到这里说明processRecord不存在,移除之
if (r.finishing) {
removeActivityFromHistoryLocked(r, reason + " hadNoApp");
removedFromHistory = true;
} else {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (no app)");
r.state = ActivityState.DESTROYED;
if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
r.app = null;
}
}
r.configChangeFlags = 0;
if (!mLRUActivities.remove(r) && hadApp) {
Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list");
}
return removedFromHistory;
}
```
这个方法首先会判断,这个要销毁的Activity的ProcessRecord是否存在,如果存在的话,做一些正常的清理工作,比如从进程中移除这个Activity对象等等,最后会执行scheduleDestroyActivity方法,这又是一个跨进程的方法,这里再提一下,这些个和Activity生命周期相关的方法,大部分都是异步的,比如这里destory调用的方法如下:
```java
@Override public void scheduleDestroyActivity(android.os.IBinder token, boolean finished, int configChanges) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder(token);
_data.writeInt(((finished)?(1):(0)));
_data.writeInt(configChanges);
mRemote.transact(Stub.TRANSACTION_scheduleDestroyActivity, _data, null, android.os.IBinder.FLAG_ONEWAY);
}
finally {
_data.recycle();
}
}
```
这里mRemote.transact方法最后一个参数FLAG_ONEWAY表示的就是异步。回到destroyActivityLocked方法,在调用完这个跨进程的方法后,后面会发送一个10秒的延迟消息:
```java
Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
```
如果执行超时了就会执行hander中调用的方法,如果正常执行最后会取消这个Handler的消息,这个我们后面分析的时候会看到,最后正常执行或者由于超时导致handler中执行的方法是同一个方法的,所以我们等会分析完onDestory方法后,会在回到AMS这里。
# 客户端调用onDestory
好了,我们继续看客户端的scheduleDestroyActivity方法:
```java
public final void scheduleDestroyActivity(IBinder token, boolean finishing,
int configChanges) {
sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
configChanges);
}
```
老套路了,我们去handler继续看:
```java
case DESTROY_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
// ondestory
handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
msg.arg2, false);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
```
继续调用handleDestroyActivity方法:
```java
private void handleDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
// 这个方法中最终调用了onDestory
ActivityClientRecord r = performDestroyActivity(token, finishing,
configChanges, getNonConfigInstance);
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.
r.window.clearContentView();
} else {
wm.removeViewImmediate(v);
}
}
if (wtoken != null && r.mPendingRemoveWindow == null) {
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.
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 c = r.activity.getBaseContext();
if (c instanceof ContextImpl) {
((ContextImpl) c).scheduleFinalCleanup(
r.activity.getClass().getName(), "Activity");
}
}
if (finishing) {
try {
// 回复AMS
ActivityManager.getService().activityDestroyed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
```
这里开始就调用performDestroyActivity这个方法,之后做一些结束清理工作,最后调用activityDestroyed来通知AMS。我们看下performDestroyActivity这个方法,不用猜了,大家肯定也都想到了会回调到Activity的onDestory方法:
```java
private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
// 获取ActivityClientRecord
ActivityClientRecord r = mActivities.get(token);
Class<? extends Activity> activityClass = null;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
if (r != null) {
activityClass = r.activity.getClass();
r.activity.mConfigChangeFlags |= configChanges;
if (finishing) {
r.activity.mFinished = true;
}
// 先执行onpause
performPauseActivityIfNeeded(r, "destroy");
if (!r.stopped) { // 如果没执行过onStop,下面开始执行
try {
// 开始执行
r.activity.performStop(r.mPreserveWindow);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to stop activity "
+ safeToComponentShortString(r.intent)
+ ": " + e.toString(), e);
}
}
r.stopped = true;
EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName(), "destroy");
}
if (getNonConfigInstance) {
try {
r.lastNonConfigurationInstances
= r.activity.retainNonConfigurationInstances();
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to retain activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
try {
r.activity.mCalled = false;
// 执行onDestory
mInstrumentation.callActivityOnDestroy(r.activity);
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) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to destroy activity " + safeToComponentShortString(r.intent)
+ ": " + e.toString(), e);
}
}
}
mActivities.remove(token); //从集合中移除这个Activity
StrictMode.decrementExpectedActivityCount(activityClass);
return r;
}
```
这里先是看下puase和stop是否有执行,如果没执行就先执行,之后会执行callActivityOnDestroy方法:
```java
public void callActivityOnDestroy(Activity activity) {
activity.performDestroy();
}
final void performDestroy() {
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy();
onDestroy();
mFragments.doLoaderDestroy();
if (mVoiceInteractor != null) {
mVoiceInteractor.detachActivity();
}
}
```
最后执行了Activit的onDestroy方法,这里也就不多说了。我们回到handleDestroyActivity方法,之后会清理些和WMS相关的,这里在AMS流程这里也不多说。我们回到AMS看下客户端回复AMS后做了些什么。
#onDestory回到AMS
```java
public final void activityDestroyed(IBinder token) {
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
synchronized (this) {
// 获取被ondestory的Activity
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityDestroyedLocked(token, "activityDestroyed");
}
}
}
```
这里取出被finish的ActivityStack,调用stack.activityDestroyedLocked方法:
```java
final void activityDestroyedLocked(IBinder token, String reason) {
final long origId = Binder.clearCallingIdentity();
try {
ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
}
if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + r);
if (isInStackLocked(r) != null) {
if (r.state == ActivityState.DESTROYING) {
cleanUpActivityLocked(r, true, false);
//
removeActivityFromHistoryLocked(r, reason);
}
}
mStackSupervisor.resumeFocusedStackTopActivityLocked();
} finally {
Binder.restoreCallingIdentity(origId);
}
}
```
这里开始我们看到remove了前面发送给Handler的消息,如果这里正常先返回了,就会在返回这里执行。如果由于超时导致Handler先执行了,那么这个方法会被Handler那里出发,总之由于这个方法是线程安全的,所以只会有一个地方触发,保证只会被执行一次。这个方法会继续调用resumeFocusedStackTopActivityLocked方法,这个方法会显示一个后面聚焦的ActivityStack,这个在AMS第三篇的文章中已经有过分析了,这里也就不做介绍了。
# 延迟处理等待finish的对象
到这里一个正常finish的流程也就结束了,回到前面finishCurrentActivityLocked方法,这个方法里我们有说到,可能有些情况不能立刻马上finish一个Activity,所以会把这些需要finish的对象放到集合中,等待显示新的Activity后,在onresume流程中会通过addIdleHandler一个Idler()消息来处理,我们看下Idler类:
```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;
IActivityManager am = ActivityManager.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 {
// 调用AMSactivityIdle
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();
}
ensureJitEnabled();
return false;
}
}
```
这里看到会触发AMS的activityIdle方法,我们到AMS看下这个方法:
```java
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
final long origId = Binder.clearCallingIdentity();
synchronized (this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
ActivityRecord r =
mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
false /* processPausingActivities */, config);
if (stopProfiling) {
if ((mProfileProc == r.app) && (mProfileFd != null)) {
try {
mProfileFd.close();
} catch (IOException e) {
}
clearProfilerLocked();
}
}
}
}
Binder.restoreCallingIdentity(origId);
}
```
我们看到这里会调用mStackSupervisor.activityIdleInternalLocked方法:
```java
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) {
.............
// Stop any activities that are scheduled to do so but have been
// waiting for the next one to start.
// stop等待stop集合中的Activity,如果他的finish标志打开,那么就finish
for (int i = 0; i < NS; i++) {
r = stops.get(i);
final ActivityStack stack = r.getStack();
if (stack != null) {
if (r.finishing) {
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
} else {
stack.stopActivityLocked(r);
}
}
}
// Finish any activities that are scheduled to do so but have been
// waiting for the next one to start.
// 处理待finish的集合
for (int i = 0; i < NF; i++) {
r = finishes.get(i);
final ActivityStack stack = r.getStack();
if (stack != null) {
activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
}
}
...................
return r;
}
```
这个方法中,我们看到会变量stops.get和finishes.get的集合,如果有需要处理的,会调用相应的方法,比如stack.finishCurrentActivityLocked,stack.destroyActivityLocked,stack.stopActivityLocked等等,这些方法之前我们也都有介绍,这里就不多叙述了。
到这里,一个完整的finish的流程就都介绍完了。finish包括了直接finish的流程和延迟finish的流程,但是他们调用的方法最后也都是相同的,所以本质其实是差不多的,相信看过前面AMS文章的同学到这里看finis流程肯定也不会感到太困难了。好了,AMS系列通过这五篇文章把主要的流程都分析过了,当然AMS是非常庞大的,还有许多细节可以值得讨论,后面有机会再分析其中的细节内容。今天这篇文章就说到这里,我们把finish的流程也用时序图总结下。

AMS源码分析(五)