// Activity was launched when user tapped a link in the Autofill Save UI - Save UI must // be restored now. if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) { restoreAutofillSaveUi(); } }
publicfinalbooleanfinishActivity(IBinder token, int resultCode, Intent resultData, int finishTask){ // Refuse possible leaked file descriptors //回传的ResultIntent中不允许包含fd,防止泄漏 if (resultData != null && resultData.hasFileDescriptors()) { thrownew IllegalArgumentException("File descriptors passed in Intent"); }
final ActivityRecord r; synchronized (mGlobalLock) { //获取ActivityRecord并保证其在栈中 r = ActivityRecord.isInStackLocked(token); //为null说明已被移出ActivityStack,视作已被finish if (r == null) { returntrue; } }
// Carefully collect grants without holding lock //检查调用方(即待finish的Activity)是否能授予result所对应Activity package访问uri的权限 final NeededUriGrants resultGrants = collectGrants(resultData, r.resultTo);
synchronized (mGlobalLock) { // Sanity check in case activity was removed before entering global lock. if (!r.isInHistory()) { returntrue; }
// Keep track of the root activity of the task before we finish it final Task tr = r.getTask(); final ActivityRecord rootR = tr.getRootActivity(); // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can // finish. //LockTask模式下,如果此为最后一个Task,则不允许被销毁 //详见:https://developer.android.com/work/dpc/dedicated-devices/lock-task-mode if (getLockTaskController().activityBlockedFromFinish(r)) { returnfalse; }
// TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked // We should consolidate. //IActivityController分发Activity状态变化 if (mController != null) { // Find the first activity that is not finishing. //寻找该Activity销毁后的下一个顶层Activity final ActivityRecord next = r.getRootTask().topRunningActivity(token, INVALID_TASK_ID); if (next != null) { // ask watcher if this is allowed boolean resumeOK = true; try { resumeOK = mController.activityResuming(next.packageName); } catch (RemoteException e) { mController = null; Watchdog.getInstance().setActivityController(null); }
if (!resumeOK) { returnfalse; } } }
// note down that the process has finished an activity and is in background activity // starts grace period //设置Activity销毁的最新时间 if (r.app != null) { r.app.setLastActivityFinishTimeIfNeeded(SystemClock.uptimeMillis()); }
finallong origId = Binder.clearCallingIdentity(); try { boolean res; finalboolean finishWithRootActivity = finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY || (finishWithRootActivity && r == rootR)) { //需要同时销毁Task // If requested, remove the task that is associated to this activity only if it // was the root activity in the task. The result code and data is ignored // because we don't support returning them across task boundaries. Also, to // keep backwards compatibility we remove the task from recents when finishing // task with root activity. //移除Task mStackSupervisor.removeTask(tr, false/*killProcess*/, finishWithRootActivity, "finish-activity"); res = true; // Explicitly dismissing the activity so reset its relaunch flag. r.mRelaunchReason = RELAUNCH_REASON_NONE; } else { //不需要同时销毁Task r.finishIfPossible(resultCode, resultData, resultGrants, "app-request", true/* oomAdj */); res = r.finishing; } return res; } finally { Binder.restoreCallingIdentity(origId); } } }
/** Completely remove all activities associated with an existing task. */ voidperformClearTask(String reason){ // Broken down into to cases to avoid object create due to capturing mStack. if (getStack() == null) { forAllActivities((r) -> { if (r.finishing) return; // Task was restored from persistent storage. r.takeFromHistory(); removeChild(r); }); } else { forAllActivities((r) -> { if (r.finishing) return; // TODO: figure-out how to avoid object creation due to capture of reason variable. r.finishIfPossible(Activity.RESULT_CANCELED, null/* resultData */, null/* resultGrants */, reason, false/* oomAdj */); }); } }
/** * Finish activity if possible. If activity was resumed - we must first pause it to make the * activity below resumed. Otherwise we will try to complete the request immediately by calling * {@link #completeFinishing(String)}. * @return One of {@link FinishRequest} values: * {@link #FINISH_RESULT_REMOVED} if this activity has been removed from the history list. * {@link #FINISH_RESULT_REQUESTED} if removal process was started, but it is still in the list * and will be removed from history later. * {@link #FINISH_RESULT_CANCELLED} if activity is already finishing or in invalid state and the * request to finish it was not ignored. */ @FinishRequestintfinishIfPossible(int resultCode, Intent resultData, NeededUriGrants resultGrants, String reason, boolean oomAdj){
//防止重复销毁 if (finishing) { return FINISH_RESULT_CANCELLED; }
//此Activity不在任务栈中 if (!isInStackLocked()) { return FINISH_RESULT_CANCELLED; }
final ActivityStack stack = getRootTask(); //应该调整顶部Activity finalboolean mayAdjustTop = (isState(RESUMED) || stack.mResumedActivity == null) && stack.isFocusedStackOnDisplay(); //应该调整全局焦点 finalboolean shouldAdjustGlobalFocus = mayAdjustTop // It must be checked before {@link #makeFinishingLocked} is called, because a stack // is not visible if it only contains finishing activities. && mRootWindowContainer.isTopDisplayFocusedStack(stack);
//暂停布局工作 mAtmService.deferWindowLayout(); try { //设置当前Activity状态为finishing makeFinishingLocked(); // Make a local reference to its task since this.task could be set to null once this // activity is destroyed and detached from task. final Task task = getTask(); //获取上一个ActivityRecord ActivityRecord next = task.getActivityAbove(this); //传递FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:重置该Task时清除此Activity if (next != null) { if ((intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { // If the caller asked that this activity (and all above it) // be cleared when the task is reset, don't lose that information, // but propagate it up to the next activity. next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); } }
//暂停输入事件分发 pauseKeyDispatchingLocked();
// We are finishing the top focused activity and its task has nothing to be focused so // the next focusable task should be focused. //应该调整顶部Activity,但此Task没有Activity可以被运行在顶部,将焦点转移至下一个可聚焦的Task if (mayAdjustTop && ((ActivityStack) task).topRunningActivity(true/* focusableOnly */) == null) { task.adjustFocusToNextFocusableTask("finish-top", false/* allowFocusSelf */, shouldAdjustGlobalFocus); }
//终止Task finalboolean endTask = task.getActivityBelow(this) == null && !task.isClearingToReuseTask(); finalint transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE; if (isState(RESUMED)) { if (endTask) { //通知Task移除已开始 mAtmService.getTaskChangeNotificationController().notifyTaskRemovalStarted( task.getTaskInfo()); } // Prepare app close transition, but don't execute just yet. It is possible that // an activity that will be made resumed in place of this one will immediately // launch another new activity. In this case current closing transition will be // combined with open transition for the new activity. //准备Activity转场动画 mDisplayContent.prepareAppTransition(transit, false);
// When finishing the activity preemptively take the snapshot before the app window // is marked as hidden and any configuration changes take place //更新Task快照 if (mAtmService.mWindowManager.mTaskSnapshotController != null) { final ArraySet<Task> tasks = Sets.newArraySet(task); mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks); mAtmService.mWindowManager.mTaskSnapshotController .addSkipClosingAppSnapshotTasks(tasks); }
// Tell window manager to prepare for this one to be removed. //设置可见性 setVisibility(false);
if (endTask) { //屏幕固定功能 mAtmService.getLockTaskController().clearLockedTask(task); // This activity was in the top focused stack and this is the last activity in // that task, give this activity a higher layer so it can stay on top before the // closing task transition be executed. //更新窗口层级 if (mayAdjustTop) { mNeedsZBoost = true; mDisplayContent.assignWindowLayers(false/* setLayoutNeeded */); } } } elseif (!isState(PAUSING)) { ... //正常不会进入此case }
/** * Sets the result for activity that started this one, clears the references to activities * started for result from this one, and clears new intents. */ privatevoidfinishActivityResults(int resultCode, Intent resultData, NeededUriGrants resultGrants){ // Send the result if needed if (resultTo != null) { if (resultTo.mUserId != mUserId) { if (resultData != null) { resultData.prepareToLeaveUser(mUserId); } } if (info.applicationInfo.uid > 0) { mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(resultGrants, resultTo.getUriPermissionsLocked()); } resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData); resultTo = null; }
// Make sure this HistoryRecord is not holding on to other resources, // because clients have remote IPC references to this object so we // can't assume that will go away and want to avoid circular IPC refs. results = null; pendingResults = null; newIntents = null; setSavedState(null/* savedState */); }
//将Result结果添加到results列表中 voidaddResultLocked(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); }
/** * Start pausing the currently resumed activity. It is an error to call this if there * is already an activity being paused or there is no resumed activity. * * @param userLeaving True if this should result in an onUserLeaving to the current activity. * @param uiSleeping True if this is happening with the user interface going to sleep (the * screen turning off). * @param resuming The activity we are currently trying to resume or null if this is not being * called as part of resuming the top activity, so we shouldn't try to instigate * a resume here if not null. * @return Returns true if an activity now is in the PAUSING state, and we are waiting for * it to tell us when it is done. */ finalbooleanstartPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming){ //已有Activity正在暂停中 if (mPausingActivity != null) { if (!shouldSleepActivities()) { // Avoid recursion among check for sleep and complete pause during sleeping. // Because activity will be paused immediately after resume, just let pause // be completed by the order of activity paused from clients. completePauseLocked(false, resuming); } } //上一个已resume的Activity ActivityRecord prev = mResumedActivity;
//既没有已resume的Activity,也没有正在resume的Activity //从栈顶找一个Activity恢复 if (prev == null) { if (resuming == null) { mRootWindowContainer.resumeFocusedStacksTopActivities(); } returnfalse; }
//不能暂停一个正在resume的Activity if (prev == resuming) { returnfalse; }
if (prev.attachedToProcess()) { try { //调度Pause生命周期事务 mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(), prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving, prev.configChangeFlags, pauseImmediately)); } catch (Exception e) { // Ignore exception, if process died other code will cleanup. mPausingActivity = null; mLastPausedActivity = null; mLastNoHistoryActivity = null; } } else { mPausingActivity = null; mLastPausedActivity = null; mLastNoHistoryActivity = null; }
// If we are not going to sleep, we want to ensure the device is // awake until the next activity is started. //获取Wakelock,确保设备awake状态直到下一个Activity启动 if (!uiSleeping && !mAtmService.isSleepingOrShuttingDownLocked()) { mStackSupervisor.acquireLaunchWakelock(); }
if (mPausingActivity != null) { // Have the window manager pause its key dispatching until the new // activity has started. If we're pausing the activity just because // the screen is being turned off and the UI is sleeping, don't interrupt // key dispatch; the same activity will pick it up again on wakeup. if (!uiSleeping) { //暂停输入事件分发 prev.pauseKeyDispatchingLocked(); }
if (pauseImmediately) { //不会进入此case // If the caller said they don't want to wait for the pause, then complete // the pause now. completePauseLocked(false, resuming); returnfalse; } else { //设置超时监听(500ms内没有完成便视为超时) prev.schedulePauseTimeout(); returntrue; }
} else { // This activity failed to schedule the // pause, so just treat it as being paused now. //未能成功暂停此Activity,从栈顶找一个Activity恢复 if (resuming == null) { mRootWindowContainer.resumeFocusedStacksTopActivities(); } returnfalse; } }
publicvoidhandlePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, PendingTransactionActions pendingActions, String reason){ ActivityClientRecord r = mActivities.get(token); if (r != null) { ... r.activity.mConfigChangeFlags |= configChanges; performPauseActivity(r, finished, reason, pendingActions);
// Make sure any pending writes are now committed. //确保所有全局任务都被处理完成 if (r.isPreHoneycomb()) { QueuedWork.waitToFinish(); } //更新标记 mSomeActivitiesChanged = true; } }
/** * Pause the activity. * @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise. */ private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason, PendingTransactionActions pendingActions){ ... //异常状态检查 if (finished) { r.activity.mFinished = true; }
// Pre-Honeycomb apps always save their state before pausing //是否需要保存状态信息(Android 3.0前无论是否finish都会触发保存) finalboolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb(); if (shouldSaveState) { //回调Activity的onSaveInstanceState方法 callActivityOnSaveInstanceState(r); }
privatevoidperformPauseActivityIfNeeded(ActivityClientRecord r, String reason){ //已暂停,直接返回 if (r.paused) { // You are already paused silly... return; }
// Always reporting top resumed position loss when pausing an activity. If necessary, it // will be restored in performResumeActivity(). //报告resume状态变更 reportTopResumedActivityChanged(r, false/* onTop */, "pausing");
try { r.activity.mCalled = false; //回调Activity的onPause方法 mInstrumentation.callActivityOnPause(r.activity); if (!r.activity.mCalled) { //必须要调用super.onPause方法 thrownew SuperNotCalledException("Activity " + safeToComponentShortString(r.intent) + " did not call through to super.onPause()"); } } catch ... //设置状态 r.setState(ON_PAUSE); }
if (prev != null) { prev.setWillCloseOrEnterPip(false); //之前的状态是否为正在停止 finalboolean wasStopping = prev.isState(STOPPING); //设置状态为已暂停 prev.setState(PAUSED, "completePausedLocked"); if (prev.finishing) { //继续finish流程 prev = prev.completeFinishing("completePausedLocked"); } elseif (prev.hasProcess()) { //Configuration发生变化时可能会设置这个flag if (prev.deferRelaunchUntilPaused) { // Complete the deferred relaunch that was waiting for pause to complete. //等待暂停完成后relaunch Activity prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch); } elseif (wasStopping) { // We are also stopping, the stop request must have gone soon after the pause. // We can't clobber it, because the stop confirmation will not be handled. // We don't need to schedule another stop, we only need to let it happen. //之前的状态为正在停止,将状态置回即可 prev.setState(STOPPING, "completePausedLocked"); } elseif (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) { // Clear out any deferred client hide we might currently have. prev.setDeferHidingClient(false); // If we were visible then resumeTopActivities will release resources before // stopping. //添加到stop列表中等待空闲时执行stop prev.addToStopping(true/* scheduleIdle */, false/* idleDelayed */, "completePauseLocked"); } } else { //App在pause过程中死亡 prev = null; } // It is possible the activity was freezing the screen before it was paused. // In that case go ahead and remove the freeze this activity has on the screen // since it is no longer visible. if (prev != null) { //停止屏幕冻结 prev.stopFreezingScreenLocked(true/*force*/); } //Activity暂停完毕 mPausingActivity = null; }
//恢复前一个顶层Activity if (resumeNext) { final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack(); if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) { mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null); } else { checkReadyForSleep(); final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null; if (top == null || (prev != null && top != prev)) { // If there are no more activities available to run, do resume anyway to start // something. Also if the top activity on the stack is not the just paused // activity, we need to go ahead and resume it to ensure we complete an // in-flight app switch. mRootWindowContainer.resumeFocusedStacksTopActivities(); } } }
if (prev != null) { //恢复按键分发 prev.resumeKeyDispatchingLocked(); ... //更新统计信息 }
// Notify when the task stack has changed, but only if visibilities changed (not just // focus). Also if there is an active pinned stack - we always want to notify it about // task stack changes, because its positioning may depend on it. //通知Task状态发生变化 if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause || (getDisplayArea() != null && getDisplayArea().hasPinnedTask())) { mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged(); mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false; } }
/** * Complete activity finish request that was initiated earlier. If the activity is still * pausing we will wait for it to complete its transition. If the activity that should appear in * place of this one is not visible yet - we'll wait for it first. Otherwise - activity can be * destroyed right away. * @param reason Reason for finishing the activity. * @return Flag indicating whether the activity was removed from history. */ ActivityRecord completeFinishing(String reason){ ... //状态检查
// If this activity is currently visible, and the resumed activity is not yet visible, then // hold off on finishing until the resumed one becomes visible. // The activity that we are finishing may be over the lock screen. In this case, we do not // want to consider activities that cannot be shown on the lock screen as running and should // proceed with finishing the activity if there is no valid next top running activity. // Note that if this finishing activity is floating task, we don't need to wait the // next activity resume and can destroy it directly. // TODO(b/137329632): find the next activity directly underneath this one, not just anywhere final ActivityRecord next = getDisplayArea().topRunningActivity( true/* considerKeyguardState */); // isNextNotYetVisible is to check if the next activity is invisible, or it has been // requested to be invisible but its windows haven't reported as invisible. If so, it // implied that the current finishing activity should be added into stopping list rather // than destroy immediately. finalboolean isNextNotYetVisible = next != null && (!next.nowVisible || !next.mVisibleRequested);
//如果此Activity当前可见,而要恢复的Activity还不可见,则推迟finish,直到要恢复的Activity可见为止 if (isCurrentVisible && isNextNotYetVisible) { // Add this activity to the list of stopping activities. It will be processed and // destroyed when the next activity reports idle. //添加到stop列表中等待空闲时执行stop addToStopping(false/* scheduleIdle */, false/* idleDelayed */, "completeFinishing"); //设置状态为stop中 setState(STOPPING, "completeFinishing"); } elseif (addToFinishingAndWaitForIdle()) { // We added this activity to the finishing list and something else is becoming resumed. // The activity will complete finishing when the next activity reports idle. No need to // do anything else here. //将此Activity添加到待finish列表中,等待空闲时执行finish } else { // Not waiting for the next one to become visible, and nothing else will be resumed in // place of this activity - requesting destruction right away. //立刻销毁此Activity activityRemoved = destroyIfPossible(reason); }
voidactivityIdleInternal(ActivityRecord r, boolean fromTimeout, boolean processPausingActivities, Configuration config){ ... // Atomically retrieve all of the other things to do. processStoppingAndFinishingActivities(r, processPausingActivities, "idle"); ... }
/** * Processes the activities to be stopped or destroyed. This should be called when the resumed * activities are idle or drawn. */ privatevoidprocessStoppingAndFinishingActivities(ActivityRecord launchedActivity, boolean processPausingActivities, String reason){ // Stop any activities that are scheduled to do so but have been waiting for the transition // animation to finish. ArrayList<ActivityRecord> readyToStopActivities = null; for (int i = mStoppingActivities.size() - 1; i >= 0; --i) { final ActivityRecord s = mStoppingActivities.get(i); finalboolean animating = s.isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS); //不在动画中或者ATMS服务正在关闭 if (!animating || mService.mShuttingDown) { //跳过正在pause的Activitiy if (!processPausingActivities && s.isState(PAUSING)) { // Defer processing pausing activities in this iteration and reschedule // a delayed idle to reprocess it again removeIdleTimeoutForActivity(launchedActivity); scheduleIdleTimeout(launchedActivity); continue; }
if (readyToStopActivities == null) { readyToStopActivities = new ArrayList<>(); } //将准备好stop的Activitiy加入列表中 readyToStopActivities.add(s);
mStoppingActivities.remove(i); } }
finalint numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size(); for (int i = 0; i < numReadyStops; i++) { final ActivityRecord r = readyToStopActivities.get(i); //Activity是否在任务栈中 if (r.isInHistory()) { if (r.finishing) { // TODO(b/137329632): Wait for idle of the right activity, not just any. //被标记为finishing,尝试销毁Activity r.destroyIfPossible(reason); } else { //否则仅仅只是stop Activity r.stopIfPossible(); } } }
// Finish any activities that are scheduled to do so but have been waiting for the next one // to start. final ArrayList<ActivityRecord> finishingActivities = new ArrayList<>(mFinishingActivities); mFinishingActivities.clear(); for (int i = 0; i < numFinishingActivities; i++) { final ActivityRecord r = finishingActivities.get(i); if (r.isInHistory()) { //立刻执行Activity的销毁流程 r.destroyImmediately(true/* removeFromApp */, "finish-" + reason); } } }
/** * Destroy and cleanup the activity both on client and server if possible. If activity is the * last one left on display with home stack and there is no other running activity - delay * destroying it until the next one starts. */ booleandestroyIfPossible(String reason){ //设置状态 setState(FINISHING, "destroyIfPossible");
// Make sure the record is cleaned out of other places. //确保此Activity已从待stop列表中移除 mStackSupervisor.mStoppingActivities.remove(this);
final ActivityStack stack = getRootTask(); final TaskDisplayArea taskDisplayArea = getDisplayArea(); final ActivityRecord next = taskDisplayArea.topRunningActivity(); finalboolean isLastStackOverEmptyHome = next == null && stack.isFocusedStackOnDisplay() && taskDisplayArea.getOrCreateRootHomeTask() != null; if (isLastStackOverEmptyHome) { // Don't destroy activity immediately if this is the last activity on the display and // the display contains home stack. Although there is no next activity at the moment, // another home activity should be started later. Keep this activity alive until next // home activity is resumed. This way the user won't see a temporary black screen. //如果Home栈存在且这是当前焦点栈中最后一个Activity,则不要立即销毁它 //将此Activity添加到待finish列表中,等待空闲时执行finish addToFinishingAndWaitForIdle(); returnfalse; } //设置finishing标记(之前设过了,这里是重复设置) makeFinishingLocked();
// If the display does not have running activity, the configuration may need to be // updated for restoring original orientation of the display. //更新可见性和屏幕显示方向 if (next == null) { mRootWindowContainer.ensureVisibilityAndConfig(next, getDisplayId(), false/* markFrozenIfConfigChanged */, true/* deferResume */); } //更新恢复栈顶Activity if (activityRemoved) { mRootWindowContainer.resumeFocusedStacksTopActivities(); }
/** * Destroy the current CLIENT SIDE instance of an activity. This may be called both when * actually finishing an activity, or when performing a configuration switch where we destroy * the current client-side object but then create a new client-side object for this same * HistoryRecord. * Normally the server-side record will be removed when the client reports back after * destruction. If, however, at this point there is no client process attached, the record will * be removed immediately. * * @return {@code true} if activity was immediately removed from history, {@code false} * otherwise. */ booleandestroyImmediately(boolean removeFromApp, String reason){ //已经被销毁或正在被销毁,直接返回 if (isState(DESTROYING, DESTROYED)) { returnfalse; }
if (hasProcess()) { //清理更新工作 if (removeFromApp) { app.removeActivity(this); if (!app.hasActivities()) { mAtmService.clearHeavyWeightProcessIfEquals(app); // Update any services we are bound to that might care about whether // their client may have activities. // No longer have activities, so update LRU list and oom adj. //更新进程信息 app.updateProcessInfo(true/* updateServiceConnectionActivities */, false/* activityChange */, true/* updateOomAdj */, false/* addPendingTopUid */); } }
boolean skipDestroy = false;
try { //调度销毁生命周期事务 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, DestroyActivityItem.obtain(finishing, configChangeFlags)); } catch (Exception e) { // We can just ignore exceptions here... if the process has crashed, our death // notification will clean things up. if (finishing) { //从历史任务中移除 removeFromHistory(reason + " exceptionInScheduleDestroy"); removedFromHistory = true; skipDestroy = true; } }
nowVisible = false;
// If the activity is finishing, we need to wait on removing it from the list to give it // a chance to do its cleanup. During that time it may make calls back with its token // so we need to be able to find it on the list and so we don't want to remove it from // the list yet. Otherwise, we can just immediately put it in the destroyed state since // we are not removing it from the list. if (finishing && !skipDestroy) { //设置状态 setState(DESTROYING, "destroyActivityLocked. finishing and not skipping destroy"); //设置销毁超时回调 mAtmService.mH.postDelayed(mDestroyTimeoutRunnable, DESTROY_TIMEOUT); } else { //设置状态 setState(DESTROYED, "destroyActivityLocked. not finishing or skipping destroy"); app = null; } } else { // Remove this record from the history. if (finishing) { //没有绑定进程,从历史任务中移除 removeFromHistory(reason + " hadNoApp"); removedFromHistory = true; } else { //没有绑定进程且不在finishing中,直接设置状态为已被销毁 setState(DESTROYED, "destroyActivityLocked. not finishing and had no app"); } }
/** * Core implementation of stopping an activity. * @param r Target activity client record. * @param info Action that will report activity stop to server. * @param saveState Flag indicating whether the activity state should be saved. * @param finalStateRequest Flag indicating if this call is handling final lifecycle state * request for a transaction. * @param reason Reason for performing this operation. */ privatevoidperformStopActivityInner(ActivityClientRecord r, StopInfo info, boolean saveState, boolean finalStateRequest /* false */, String reason){ if (r != null) { ... //异常状态处理
// One must first be paused before stopped... //如果没有被暂停则先执行pause生命周期 performPauseActivityIfNeeded(r, reason);
/** * Calls {@link Activity#onStop()} and {@link Activity#onSaveInstanceState(Bundle)}, and updates * the client record's state. * All calls to stop an activity must be done through this method to make sure that * {@link Activity#onSaveInstanceState(Bundle)} is also executed in the same call. */ privatevoidcallActivityOnStop(ActivityClientRecord r, boolean saveState, String reason){ // Before P onSaveInstanceState was called before onStop, starting with P it's // called after. Before Honeycomb state was always saved before onPause. //这里shouldSaveState为true,因为activity.mFinished早在performPauseActivity的时候就被设为了true finalboolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null && !r.isPreHoneycomb(); //targetSdkVersion为Android P (Android 9)之前 finalboolean isPreP = r.isPreP(); if (shouldSaveState && isPreP) { callActivityOnSaveInstanceState(r); }
// Disallow entering picture-in-picture after the activity has been stopped //stop后禁用画中画 mCanEnterPictureInPicture = false;
if (!mStopped) { //分发PreStopped事件,执行所有注册的ActivityLifecycleCallbacks的onActivityPreStopped回调 dispatchActivityPreStopped(); //关闭所有子窗口 if (mWindow != null) { mWindow.closeAllPanels(); }
// If we're preserving the window, don't setStoppedState to true, since we // need the window started immediately again. Stopping the window will // destroys hardware resources and causes flicker. if (!preserveWindow && mToken != null && mParent == null) { //设置停止状态,释放硬件资源,销毁Surface WindowManagerGlobal.getInstance().setStoppedState(mToken, true); }
publicvoidhandleDestroyActivity(IBinder token, boolean finishing, int configChanges, boolean getNonConfigInstance, String reason){ //执行onDestroy生命周期 ActivityClientRecord r = performDestroyActivity(token, finishing, configChanges, getNonConfigInstance, reason); if (r != null) { //清理之前设置的延时移除的window cleanUpPendingRemoveWindows(r, finishing); WindowManager wm = r.activity.getWindowManager(); View v = r.activity.mDecor; if (v != null) { if (r.activity.mVisibleFromServer) { mNumVisibleActivities--; } IBinder wtoken = v.getWindowToken(); if (r.activity.mWindowAdded) { if (r.mPreserveWindow) { // Hold off on removing this until the new activity's // window is being added. r.mPendingRemoveWindow = r.window; r.mPendingRemoveWindowManager = wm; // We can only keep the part of the view hierarchy that we control, // everything else must be removed, because it might not be able to // behave properly when activity is relaunching. //从DecorView中移除ContentView r.window.clearContentView(); } else { //立刻执行View的移除操作,释放硬件资源,销毁Surface,回调View.onDetachedFromWindow wm.removeViewImmediate(v); } } if (wtoken != null && r.mPendingRemoveWindow == null) { //移除指定Window下的所有rootView WindowManagerGlobal.getInstance().closeAll(wtoken, r.activity.getClass().getName(), "Activity"); } elseif (r.mPendingRemoveWindow != null) { // We're preserving only one window, others should be closed so app views // will be detached before the final tear down. It should be done now because // some components (e.g. WebView) rely on detach callbacks to perform receiver // unregister and other cleanup. //移除指定Window下除了当前DecorView以外的所有rootView WindowManagerGlobal.getInstance().closeAllExceptView(token, v, r.activity.getClass().getName(), "Activity"); } r.activity.mDecor = null; } if (r.mPendingRemoveWindow == null) { // If we are delaying the removal of the activity window, then // we can't clean up all windows here. Note that we can't do // so later either, which means any windows that aren't closed // by the app will leak. Well we try to warning them a lot // about leaking windows, because that is a bug, so if they are // using this recreate facility then they get to live with leaks. WindowManagerGlobal.getInstance().closeAll(token, r.activity.getClass().getName(), "Activity"); }
// Mocked out contexts won't be participating in the normal // process lifecycle, but if we're running with a proper // ApplicationContext we need to have it tear down things // cleanly. //清理Context Context c = r.activity.getBaseContext(); if (c instanceof ContextImpl) { ((ContextImpl) c).scheduleFinalCleanup( r.activity.getClass().getName(), "Activity"); } } if (finishing) { try { //处理一些销毁后的事项,移除超时回调等 ActivityTaskManager.getService().activityDestroyed(token); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } mSomeActivitiesChanged = true; }
// dismiss any dialogs we are managing. //关闭所有被管理的Dialog if (mManagedDialogs != null) { finalint numDialogs = mManagedDialogs.size(); for (int i = 0; i < numDialogs; i++) { final ManagedDialog md = mManagedDialogs.valueAt(i); if (md.mDialog.isShowing()) { md.mDialog.dismiss(); } } mManagedDialogs = null; }
// close any cursors we are managing. //关闭所有被管理的Cursor synchronized (mManagedCursors) { int numCursors = mManagedCursors.size(); for (int i = 0; i < numCursors; i++) { ManagedCursor c = mManagedCursors.get(i); if (c != null) { c.mCursor.close(); } } mManagedCursors.clear(); }
// Close any open search dialog //关闭系统搜索服务的弹窗 if (mSearchManager != null) { mSearchManager.stopSearch(); }
if (mActionBar != null) { mActionBar.onDestroy(); }