上一篇我们分析了Activity的启动流程,由于代码量很大,还是没有分析的很详细,但是基本流程都出来了,更详细的东西还是要去看源码。这一章来分析Activity的finish过程,分析一下finish的过程到底做了哪些处理,最后对Activity的整个启动过程以及finish过程绘制流程图,以方便我们记忆。
finish代码分析
// /frameworks/base/core/java/android/app/Activity.java
/**
* Call this when your activity is done and should be closed. The
* ActivityResult is propagated back to whoever launched you via
* onActivityResult().
*/
public void finish() {
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
调用的finish函数中的参数可以传如下值:
/** @hide Task isn't finished when activity is finished */
public static final int DONT_FINISH_TASK_WITH_ACTIVITY = 0;
/**
* @hide Task is finished if the finishing activity is the root of the task. To preserve the
* past behavior the task is also removed from recents.
*/
public static final int FINISH_TASK_WITH_ROOT_ACTIVITY = 1;
/**
* @hide Task is finished along with the finishing activity, but it is not removed from
* recents.
*/
public static final int FINISH_TASK_WITH_ACTIVITY = 2;
根据注释,可知各个参数值的意义如下:
- DONT_FINISH_TASK_WITH_ACTIVITY:销毁activity的时候不销毁task
- FINISH_TASK_WITH_ROOT_ACTIVITY:如果要销毁的activity是task的根Activity,则将activity所在的task也结束并从最近task中移除
- FINISH_TASK_WITH_ACTIVITY:无论什么情况,只要销毁activity,就将Activity所在的task也结束
接下来就来分析一下这个finish函数的流程。上文已经提到了finish函数的源码,调用的是一个带参的finish函数:
// frameworks/base/core/java/android/app/Activity.java
/**
* Finishes the current activity and specifies whether to remove the task associated with this
* activity.
*/
private void finish(int finishTask) {
if (mParent == null) { //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);
}
//调用AMS的finishActivity方法
if (ActivityManager.getService()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true; //【此操作很关键,很多生命周期流程都有对该变量的判断】
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
...//是否自动填充的判断处理
}
跨进程调用AMS.finishActivity函数:
// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/**
* This is the internal entry point for handling Activity.finish().
*
* @param token The Binder token referencing the Activity we want to finish.
* @param resultCode Result code, if any, from this Activity.
* @param resultData Result data (Intent), if any, from this Activity.
* @param finishTask Whether to finish the task associated with this Activity.
*
* @return Returns true if the activity successfully finished, or false if it is still running.
*/
@Override
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
.... // Refuse possible leaked file descriptors
synchronized(this) {
ActivityRecord r = ActivityRecord.isInStackLocked(token); //【r为当前要finish的activity】
if (r == null) {
return true;
}
// Keep track of the root activity of the task before we finish it
TaskRecord tr = r.getTask(); //【获取当前要销毁的Activity所在的Task】
ActivityRecord rootR = tr.getRootActivity(); //【rootR为即将要finish的Activity所在的task的根Activity(默认task的根Activity指的是在AndroidManifest.xml中定义的<action android:name="android.intent.action.MAIN" />;如果使用singleInstance模式启动则task只有该Activity,根Activity=null)】
if (rootR == null) {
Slog.w(TAG, "Finishing task with all activities already finished");
}
// Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
// finish.
if (mLockTaskController.activityBlockedFromFinish(r)) {
return false;
}
if (mController != null) { //【mController通常情况都为null】
... //如果存在下一个resume的activity,则调用IActivityController.activityResuming进行通知
}
final long origId = Binder.clearCallingIdentity();
try {
boolean res;
final boolean finishWithRootActivity =
finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
//【因为finishTask =DONT_FINISH_TASK_WITH_ACTIVITY,该条件不满足】
if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
|| (finishWithRootActivity && r == rootR)) {
...
} else {
res = tr.getStack().requestFinishActivityLocked(token, resultCode,
resultData, "app-request", true); //【关键操作】调用ActivityStack函数销毁activity
if (!res) {
Slog.i(TAG, "Failed to finish by app-request");
}
}
return res;
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
可以看到关键操作是调用ActiivtyStack.requestFinishActivityLocked函数,所以接下来看看这个函数:
// /frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
/**
* @return Returns true if the activity is being finished, false if for
* some reason it is being left as-is.
*/
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Intent resultData, String reason, boolean oomAdj) {
ActivityRecord r = isInStackLocked(token); //【r即是将要销毁的activity】
if (r == null) {
return false;
}
finishActivityLocked(r, resultCode, resultData, reason, oomAdj); //【==关键操作】
return true;
}
可见,关键操作是调用ActivityStack.finishActivityLocked函数
// /frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
/**
* See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)}
*/
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj) {
return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
}
/**
* @return Returns true if this activity has been removed from the history
* list, or false if it is still in the list and will be removed later.
*/
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj, boolean pauseImmediately) {
if (r.finishing) { //【当前是否为finishing状态,r.finishing=false】
Slog.w(TAG, "Duplicate finish request for " + r);
return false;
}
mWindowManager.deferSurfaceLayout(); //【暂停布局】
try {
r.makeFinishingLocked(); //【通知task栈中有变化,会设置r.finish=true】
final TaskRecord task = r.getTask();
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
r.userId, System.identityHashCode(r),
task.taskId, r.shortComponentName, reason);
final ArrayList<ActivityRecord> activities = task.mActivities; //【获取task中的activity】
final int index = activities.indexOf(r);
if (index < (activities.size() - 1)) {
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();
adjustFocusedActivityStack(r, "finishActivity"); //【调整activity栈】
finishActivityResultsLocked(r, resultCode, resultData); //【Activity的销毁结果】
final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
if (mResumedActivity == r) { //【mResumedActivity就是当前正要销毁的activity,该条件满足】
...
if (endTask) { //【endTask=false】
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) { //【mPausingActivity=null】
...
//执行pausing流程,最终也会调用下面的finishCurrentActivityLocked方法
startPausingLocked(false, false, null, pauseImmediately);
}
if (endTask) { //【endTask=false】
mService.getLockTaskController().clearLockedTask(task);
}
} else if (!r.isState(PAUSING)) {//【条件不满足,不执行】
...
//如果当前要销毁的activity不是mResumedActivity,则直接finish该activity
final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj,
"finishActivityLocked") == null;
return removedActivity;
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
}
return false;
} finally {
mWindowManager.continueSurfaceLayout(); //【继续布局,至此,finish函数执行完毕】
}
}
该函数主要完成的事情:
1. 先判断当前是否为finishing状态,如果是, 则直接返回;
2. 如果当前不是finishing状态,则先暂停布局(deferSurfaceLayout),通知Task Stack有变化(ActivityRecord.makeFinishingLocked);
3. 获取Activity的finish结果(finishActivityResultsLocked)
4. 如果当前在前台的Activity与要销毁的activity一致,且当前没有正在pausing的activity,则进行pause操作(startPausingLocked);
5.最后,继续布局(continueSurfaceLayout)。到此处,finish函数中的同步操作就执行完毕了。
- 先来看看ActivityRecord.makeFinishingLocked函数:
///frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
void makeFinishingLocked() {
if (finishing) { //【finishing = false】
return;
}
finishing = true;
if (stopped) { //【stopped=false】
clearOptionsLocked();
}
if (service != null) { //【service即是AMS,不为null】
service.mTaskChangeNotificationController.notifyTaskStackChanged();
}
}
- 接着看看finishActivityResultsLocked函数
/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
// send the result
ActivityRecord resultTo = r.resultTo;
if (resultTo != null) { //【resultTo = null,不执行】
...
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);
}
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;
}
- 最后看看ActivityStack.startPausingLocked函数:
///frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
/**
* 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.
* @param pauseImmediately True if the caller does not want to wait for the activity callback to
* complete pausing.
* @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, boolean pauseImmediately) {
if (mPausingActivity != null) { //【mPausingActivity=null】
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.getState());
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);
}
}
ActivityRecord prev = mResumedActivity;
if (prev == null) { //【prev即是将要销毁的activity,不为null】
if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed");
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
return false;
}
if (prev == resuming) { //【resuming=null】
Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
return false;
}
mPausingActivity = prev; //【为mPausingActivity赋值】
mLastPausedActivity = prev;//【为mLastPausedActivity赋值】
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
prev.setState(PAUSING, "startPausingLocked"); //【设置当前要销毁的activity的状态为PAUSING】
prev.getTask().touchActiveTime();
clearLaunchTime(prev);
mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());
mService.updateCpuStats();
if (prev.app != null && prev.app.thread != null) { //【条件满足】
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLogTags.writeAmPauseActivity(prev.userId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving);
mService.updateUsageStats(prev, false);
//【执行activity的pausing过程】
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
...
}
....//【休眠情况处理】
if (mPausingActivity != null) { //【上文进行了赋值,mPausingActivity即是要销毁的activity,如果pausing流程执行成功,则该值不为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) { //【uiSleeping=false】
prev.pauseKeyDispatchingLocked();
}
//是否立即完成pausing过程,此处【pauseImmediately=!ActivityStackSupervisor#PAUSE_IMMEDIATELY=false】
if (pauseImmediately) {//不执行
...
completePauseLocked(false, resuming);
return false;
} else {//延迟执行,最终还是会调用上面的completePauseLocked方法
schedulePauseTimeout(prev); //【设置超时时间】
return true;
}
} else {
...
return false;
}
}
可以看到,这个函数里有两个关键操作:
- ClientLifecycleManager.scheduleTransaction:将PauseActivityItem设置给ClientTransaction对象
- ActivityStack.schedulePauseTimeout:设置pause超时时间
☆ scheduleTransaction流程
具体的scheduleTransaction过程可以看 https://blog.csdn.net/a2923790861/article/details/108711598
这里放一张类图:
以及流程图:
☆ shedulePauseTimeout函数
// How long we wait until giving up on the last activity to pause. This
// is short because it directly impacts the responsiveness of starting the
// next activity.
private static final int PAUSE_TIMEOUT = 500;
/**
* Schedule a pause timeout in case the app doesn't respond. We don't give it much time because
* this directly impacts the responsiveness seen by the user.
*/
private void schedulePauseTimeout(ActivityRecord r) {
final Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
msg.obj = r;
r.pauseTime = SystemClock.uptimeMillis();
mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); //【发送500ms的延时消息PAUSE_TIMEOUT_MSG】
}
>ActivityStack.java
private class ActivityStackHandler extends Handler {
ActivityStackHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case PAUSE_TIMEOUT_MSG: {
ActivityRecord r = (ActivityRecord)msg.obj;
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
Slog.w(TAG, "Activity pause timeout for " + r);
synchronized (mService) {
if (r.app != null) {
mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
}
//延迟操作时间到了之后,查看pausing过程情况
activityPausedLocked(r.appToken, true);
}
} break;
......
}
}
}
在Activity的pausing过程执行完毕以后,需要执行后续的finish操作,到ActivityStack#activityPausedLocked方法
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);//r !=null
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
//如果pausing执行成功,则此时mPausingActivity即是要销毁的activity==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 {
//完成pausing过程,最终还是调用下面的finishCurrentActivityLocked方法
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.isState(PAUSING)) {
r.setState(PAUSED, "activityPausedLocked");
if (r.finishing) {
if (DEBUG_PAUSE) Slog.v(TAG,
"Executing finish of failed to pause activity: " + r);
//pausing过程失败,finish掉activity
finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false,
"activityPausedLocked");
}
}
}
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
调用了completePauseLocked方法
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
//此时mPausingActivity即是要销毁的activity!=null
if (prev != null) {
prev.setWillCloseOrEnterPip(false);
final boolean wasStopping = prev.isState(STOPPING);
prev.setState(PAUSED, "completePausedLocked");
//在finishActivityLocked方法中,调用了要销毁的activity的makeFinishingLocked()方法。所以prev.finishing=true
if (prev.finishing) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
//【finish当前activity】
prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
"completedPausedLocked");
} else if (prev.app != null) {//不执行
....
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
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*/);
}
mPausingActivity = null;
}
....
}
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj,
String reason) {
// 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.
// 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.
// 获取顶部正在运行的Activity
final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(
true /* considerKeyguardState */);
if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
&& next != null && !next.nowVisible) {
// 如果当前要结束的Activity不在正在停止列表中则添加到停止列表中
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */);
}
if (DEBUG_STATES) Slog.v(TAG_STATES,
"Moving to STOPPING: "+ r + " (finish requested)");
r.setState(STOPPING, "finishCurrentActivityLocked");
if (oomAdj) {
mService.updateOomAdjLocked();
}
return r;
}
// make sure the record is cleaned out of other places.
// 从各个列表中清理这个将要被finish的Activity
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(r);
final ActivityState prevState = r.getState();// 存储清理之前的状态
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
r.setState(FINISHING, "finishCurrentActivityLocked");// 设置为正在finish状态
// 判断当前正在清理的Activity是否在当前获取焦点的栈中
final boolean finishingActivityInNonFocusedStack
= r.getStack() != mStackSupervisor.getFocusedStack()
&& prevState == PAUSED && mode == FINISH_AFTER_VISIBLE;
if (mode == FINISH_IMMEDIATELY
|| (prevState == PAUSED
&& (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
|| finishingActivityInNonFocusedStack
|| prevState == STOPPING
|| prevState == STOPPED
|| prevState == ActivityState.INITIALIZING) {
r.makeFinishingLocked();
// 销毁Activity
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm:" + reason);
......
return activityRemoved ? null : r;
}
.....
return r;
}
这里是开始销毁Activity,首先要保存状态,然后标记开始finish,然后调用destroyActivityLocked方法开始销毁。
final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
...
// 清理Activity
cleanUpActivityLocked(r, false, false);
final boolean hadApp = r.app != null;
if (hadApp) {
...
boolean skipDestroy = false;
try {
//执行DestroyActivityItem事务,最后会调用DestroyActivityItem的execute方法
mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,DestroyActivityItem.obtain(r.finishing, r.configChangeFlags));
} catch (Exception e) {
...
}
...
return removedFromHistory;
}
复制代码
这里主要有两部操作,第一步是cleanUpActivityLocked,第二步是scheduleDestroyActivity。我们先看第一步。
ActivityStack.cleanUpActivityLocked
private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean setState) {
//将指向该销毁的Activity的引用都置空
onActivityRemovedFromStack(r);
r.deferRelaunchUntilPaused = false;
r.frozenBeforeDestroy = false;
if (setState) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)");
r.setState(DESTROYED, "cleanupActivityLocked");
if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r);
r.app = null;
}
// Inform supervisor the activity has been removed.
//从列表中移除该Activity对象
mStackSupervisor.cleanupActivity(r);
// Remove any pending results.
if (r.finishing && r.pendingResults != null) {
for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
PendingIntentRecord rec = apr.get();
if (rec != null) {
mService.cancelIntentSenderLocked(rec, false);
}
}
r.pendingResults = null;
}
// 是否清理服务,这里cleanServices=false
if (cleanServices) {
cleanUpActivityServicesLocked(r);
}
// Get rid of any pending idle timeouts.
removeTimeoutsForActivityLocked(r);
// Clean-up activities are no longer relaunching (e.g. app process died). Notify window
// manager so it can update its bookkeeping.
mWindowManager.notifyAppRelaunchesCleared(r.appToken);
}
ApplicationThreadNative.scheduleDestroyActivity
最终会调用DestoryActivityItem的execute方法
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
//client为ActivityThread
client.handleDestroyActivity(token, mFinished, mConfigChanges,
false /* getNonConfigInstance */, "DestroyActivityItem");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
ActivityThread.handleDestroyActivity
private void handleDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
ActivityClientRecord r = performDestroyActivity(token, finishing,
configChanges, getNonConfigInstance);
...
if (finishing) {
try {
ActivityManager.getService().activityDestroyed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
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;
}
//r.pause==true,不需要执行pausing过程
performPauseActivityIfNeeded(r, "destroy");
//如果还没执行过stop过程,则执行stop过程
if (!r.stopped) {
callActivityOnStop(r, false /* saveState */, "destroy");
}
....
try {
r.activity.mCalled = false;
//执行destroy过程,最终调用activity的onDestroy方法
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);
}
}
r.setState(ON_DESTROY);
}
mActivities.remove(token);
StrictMode.decrementExpectedActivityCount(activityClass);
return r;
}
再回到AMS的activityDestroyed方法中来
public final void activityDestroyed(IBinder token) {
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
synchronized (this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityDestroyedLocked(token, "activityDestroyed");
}
}
}
ActivityStack.activityDestroyedLocked
final void activityDestroyedLocked(IBinder token, String reason) {
final long origId = Binder.clearCallingIdentity();
try {
ActivityRecord r = ActivityRecord.forTokenLocked(token);
...
if (isInStackLocked(r) != null) {
if (r.state == ActivityState.DESTROYING) {
cleanUpActivityLocked(r, true, false);
removeActivityFromHistoryLocked(r, null, reason);
}
}
mStackSupervisor.resumeFocusedStackTopActivityLocked();
} finally {
Binder.restoreCallingIdentity(origId);
}
}
这里主要是两步,第一个是调用cleanUpActivityLocked方法,清理Activity,前面我们分析过了,不再分析。然后是调用removeActivityFromHistoryLocked方法,就是将该结束的Activity从历史列表中删除.
到这里Activity的finish就分析完了,从这里我们主要学到的是finish的过程,以及finish过程中系统做了哪些处理,我们在写代码过程中应该做那些处理。