开篇
本篇以android-11.0.0_r25作为基础解析
咱们在之前的几篇Activity
发动流程剖析中现已了解了Activity
一半的生命周期,接下来这篇文章咱们就来剖析一下Activity
毁掉相关的生命周期
前几期文章回忆:
Android源码剖析 – Activity发动流程(上)
Android源码剖析 – Activity发动流程(中)
Android源码剖析 – Activity发动流程(下)
触发毁掉
已然要剖析Activity
毁掉流程,那咱们就从最常见的进口Activity.finish
下手
public void finish() {
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
默许的finish
办法调用了另一个同名重载办法,承受一个int类型的参数标明是否需求在毁掉Activity
的一起毁掉Task
,该参数有以下三种:
-
DONT_FINISH_TASK_WITH_ACTIVITY
:默许参数,表明在毁掉Activity
的时分不要毁掉Task
-
FINISH_TASK_WITH_ROOT_ACTIVITY
:当Activity
为跟Activity
的时分,毁掉的一起毁掉Task
,一起这个使命也会从最近使命中移除 -
FINISH_TASK_WITH_ACTIVITY
:毁掉Activity
的时分一起毁掉Task
,但不会从最近使命中移除
private void finish(int finishTask) {
if (mParent == null) {
//当finish后才可能会触发onActivityResult回调
//这儿预备将result回来给之前调用startActivityForResult的Activity
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
try {
//两个Activity可能处于不同进程中,做进程间通信的预备
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
//调用ATMS毁掉Activity
if (ActivityTaskManager.getService()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
// 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();
}
}
onActivityResult
回调是在对应Activity
resume
时才可能触发,详细进程后边会剖析,将ActivityRecord.Token
和Result
作为参数调用ATMS.finishActivity
办法
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
// Refuse possible leaked file descriptors
//回传的ResultIntent中不答应包含fd,避免走漏
if (resultData != null && resultData.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
final ActivityRecord r;
synchronized (mGlobalLock) {
//获取ActivityRecord并保证其在栈中
r = ActivityRecord.isInStackLocked(token);
//为null说明已被移出ActivityStack,视作已被finish
if (r == null) {
return true;
}
}
// 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()) {
return true;
}
// 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)) {
return false;
}
// 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) {
return false;
}
}
}
// 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());
}
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)) { //需求一起毁掉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);
}
}
}
这个办法里分了两个case,当需求一起毁掉Task
的时分,直接调用ActivityStackSupervisor.removeTask
,当不需求一起毁掉Task
的时分,调用ActivityRecord.finishIfPossible
咱们先看需求一起毁掉Task
的case
void removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason) {
if (task.mInRemoveTask) {
// Prevent recursion.
return;
}
task.mInRemoveTask = true;
try {
//履行Task移除操作
task.performClearTask(reason);
//对Task履行杀进程,从最近使命列表移除等操作
cleanUpRemovedTaskLocked(task, killProcess, removeFromRecents);
//封闭LockTask形式
mService.getLockTaskController().clearLockedTask(task);
//告诉Task状况发生改变
mService.getTaskChangeNotificationController().notifyTaskStackChanged();
//将最近使命持久化保存
if (task.isPersistable) {
mService.notifyTaskPersisterLocked(null, true);
}
} finally {
task.mInRemoveTask = false;
}
}
本篇文章咱们首要重视的是Activity
毁掉流程,至于进程的封闭,最近使命列表的更新咱们在这儿就不关怀了,而这儿Activity
毁掉的要点在于Task.performClearTask
办法
/** Completely remove all activities associated with an existing task. */
void performClearTask(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 */);
});
}
}
咱们看后半部分代码能够发现,这个办法对Task
中一切未毁掉的Activity
都履行了ActivityRecord.finishIfPossible
办法,这样途径就和上面ATMS.finishActivity
办法中第二个case统一了
/**
* 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.
*/
@FinishRequest int finishIfPossible(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
final boolean mayAdjustTop = (isState(RESUMED) || stack.mResumedActivity == null)
&& stack.isFocusedStackOnDisplay();
//应该调整大局焦点
final boolean 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);
}
//将Result信息写入到对应ActivityRecord中,待后边resume的时分触发onActivityResult回调
finishActivityResults(resultCode, resultData, resultGrants);
//终止Task
final boolean endTask = task.getActivityBelow(this) == null
&& !task.isClearingToReuseTask();
final int 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 (stack.mPausingActivity == null) {
//开端暂停此Activity
stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
null /* resuming */);
}
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 */);
}
}
} else if (!isState(PAUSING)) {
... //正常不会进入此case
}
return FINISH_RESULT_REQUESTED;
} finally {
//康复布局作业
mAtmService.continueWindowLayout();
}
}
这个办法中,咱们需求重视一下关于Result
信息的处理,这儿调用了finishActivityResults
办法,将Result
信息写入到对应ActivityRecord
中,待后边resume
的时分触发onActivityResult
回调
/**
* Sets the result for activity that started this one, clears the references to activities
* started for result from this one, and clears new intents.
*/
private void finishActivityResults(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列表中
void addResultLocked(ActivityRecord from, String resultWho,
int requestCode, int resultCode,
Intent resultData) {
ActivityResult r = new ActivityResult(from, resultWho,
requestCode, resultCode, resultData);
if (results == null) {
results = new ArrayList<ResultInfo>();
}
results.add(r);
}
这个办法很简单,便是将Result
信息增加到ActivityRecord.results
列表中
然后咱们持续沿着finish
主线链路走,后边有一个isState
的判别,正常来说,ActivityRecord
的state
应该为RESUMED
,详细为什么咱们能够回忆一下之前剖析的Activity
发动流程,在ActivityStackSupervisor.realStartActivityLocked
办法终究,会调用ActivityStack.minimalResumeActivityLocked
,在这个办法中,会将ActivityRecord
的state
设置为RESUMED
,由于ClientTransaction
的履行是经过Handler.sendMessage
进行的,所以早在Activity
onCreate
之前,ActivityRecord
的状况就现已被设为了RESUMED
根据以上剖析,咱们会走进isState(RESUMED)
这个case中,接着调用ActivityStack.startPausingLocked
办法暂停Activity
/**
* 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.
*/
final boolean startPausingLocked(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();
}
return false;
}
//不能暂停一个正在resume的Activity
if (prev == resuming) {
return false;
}
//设置各种状况
mPausingActivity = prev;
mLastPausedActivity = prev;
mLastNoHistoryActivity = prev.isNoHistory() ? prev : null;
prev.setState(PAUSING, "startPausingLocked");
prev.getTask().touchActiveTime();
clearLaunchTime(prev);
//更新计算信息
mAtmService.updateCpuStats();
boolean pauseImmediately = false;
... //当时流程下pauseImmediately一直为false
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);
return false;
} else {
//设置超时监听(500ms内没有完结便视为超时)
prev.schedulePauseTimeout();
return true;
}
} else {
// This activity failed to schedule the
// pause, so just treat it as being paused now.
//未能成功暂停此Activity,从栈顶找一个Activity康复
if (resuming == null) {
mRootWindowContainer.resumeFocusedStacksTopActivities();
}
return false;
}
}
能够看到,和Activity
发动流程相似,该办法里面调用了ClientLifecycleManager.scheduleTransaction
办法来调度Activity
暂停的生命周期,详细是怎样调度的能够看我之前的文章 Android源码剖析 – Activity发动流程(下),里面剖析了ClientTransaction
业务是怎样被调度履行的
了解完后咱们就能够知道,生命周期业务的履行也就相当于分别调用ActivityLifecycleItem
的preExecute
、execute
、postExecute
办法,而PauseActivityItem
没有重写preExecute
办法,所以咱们就顺次剖析其execute
、postExecute
办法就好了
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
}
ClientTransactionHandler
这个咱们之前说过,这是一个抽象类,被ActivityThread
继承实现,所以这儿实际上便是调用ActivityThread.handlePauseActivity
办法
handlePauseActivity
public void handlePauseActivity(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都会触发保存)
final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
if (shouldSaveState) {
//回调Activity的onSaveInstanceState办法
callActivityOnSaveInstanceState(r);
}
performPauseActivityIfNeeded(r, reason);
...//回调OnActivityPausedListener,现在看来只要NFC部分有注册这个回调
... //Android 3.0之前的特别处理
//回来保存状况的Bundle
return shouldSaveState ? r.state : null;
}
private void performPauseActivityIfNeeded(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办法
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
+ " did not call through to super.onPause()");
}
} catch ...
//设置状况
r.setState(ON_PAUSE);
}
这一条调用链路看下来仍是很简单的,和之前咱们剖析过的其他生命周期调用是一个套路,这儿显现调用了callActivityOnSaveInstanceState
办法保存状况信息
private void callActivityOnSaveInstanceState(ActivityClientRecord r) {
r.state = new Bundle();
r.state.setAllowFds(false);
if (r.isPersistable()) {
r.persistentState = new PersistableBundle();
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}
}
经过Instrumentation
调用Activity.performSaveInstanceState
办法
final void performSaveInstanceState(@NonNull Bundle outState) {
//分发PreSaveInstanceState事情,履行一切注册的ActivityLifecycleCallbacks的onActivityPreSaveInstanceState回调
dispatchActivityPreSaveInstanceState(outState);
//回调onSaveInstanceState
onSaveInstanceState(outState);
//保存受办理的Dialog的状况
saveManagedDialogs(outState);
//同享元素动画相关
mActivityTransitionState.saveState(outState);
//保存权限恳求状况
storeHasCurrentPermissionRequest(outState);
//分发PostSaveInstanceState事情,履行一切注册的ActivityLifecycleCallbacks的onActivityPostSaveInstanceState回调
dispatchActivityPostSaveInstanceState(outState);
}
终究回调Activity.onSaveInstanceState
办法
protected void onSaveInstanceState(@NonNull Bundle outState) {
//保存窗口信息
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
//保存Fragment状况
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
//主动填充相关
if (mAutoFillResetNeeded) {
outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
getAutofillManager().onSaveInstanceState(outState);
}
//分发SaveInstanceState事情,履行一切注册的ActivityLifecycleCallbacks的onActivitySaveInstanceState回调
dispatchActivitySaveInstanceState(outState);
}
保存状况的流程就基本完结了,咱们再回过头来看onPause
的触发
在上面performPauseActivityIfNeeded
办法中有一行代码调用了Instrumentation.callActivityOnPause
办法,
经过Instrumentation
调用了Activity.performPause
办法
final void performPause() {
//分发PrePaused事情,履行一切注册的ActivityLifecycleCallbacks的onActivityPrePaused回调
dispatchActivityPrePaused();
mDoReportFullyDrawn = false;
//FragmentManager分发pause状况
mFragments.dispatchPause();
mCalled = false;
//回调onPause
onPause();
mResumed = false;
//Target Sdk 9以上(Android 2.3)需求保证在onPause中调用super.onPause办法
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
//分发PostPaused事情,履行一切注册的ActivityLifecycleCallbacks的onActivityPostPaused回调
dispatchActivityPostPaused();
}
履行onPause
回调
protected void onPause() {
//分发Paused事情,履行一切注册的ActivityLifecycleCallbacks的onActivityPaused回调
dispatchActivityPaused();
//主动填充相关
if (mAutoFillResetNeeded) {
if (!mAutoFillIgnoreFirstResumePause) {
View focus = getCurrentFocus();
if (focus != null && focus.canNotifyAutofillEnterExitEvent()) {
getAutofillManager().notifyViewExited(focus);
}
} else {
// reset after first pause()
mAutoFillIgnoreFirstResumePause = false;
}
}
//内容捕获服务
notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_PAUSE);
//super.onPause标示为已被履行
mCalled = true;
}
到此停止,Activity
的onPause
生命周期现已基本走完了,此刻咱们再回到PauseActivityItem.postExecute
办法中做一些善后处理
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
//mDontReport为咱们之前obtain办法中传入的pauseImmediately参数,一直为false
if (mDontReport) {
return;
}
try {
// TODO(lifecycler): Use interface callback instead of AMS.
//调用ATMS.activityPaused办法
ActivityTaskManager.getService().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
这儿调用ATMS.activityPaused
办法回到system_server
进程处理Activity
暂停后的事项
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized (mGlobalLock) {
//经过ActivityRecord.Token获取ActivityRecord
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
r.activityPaused(false);
}
}
Binder.restoreCallingIdentity(origId);
}
调用ActivityRecord.activityPaused
办法持续处理
void activityPaused(boolean timeout) {
final ActivityStack stack = getStack();
if (stack != null) {
//移除超时监听
removePauseTimeout();
if (stack.mPausingActivity == this) {
//暂停布局作业
mAtmService.deferWindowLayout();
try {
stack.completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
} finally {
//康复布局作业
mAtmService.continueWindowLayout();
}
return;
} else { //暂停Activity失利
if (isState(PAUSING)) {
setState(PAUSED, "activityPausedLocked");
if (finishing) {
completeFinishing("activityPausedLocked");
}
}
}
}
//更新Activity可见性
mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
}
正常情况下会进入到ActivityStack.completePauseLocked
办法中,但在暂停Activity
失利的情况下,假如当时状况为PAUSING
,则直接将其状况置为PAUSED
已暂停,假如被标记为finishing
,则会调用ActivityRecord.completeFinishing
持续finish
流程,这其实和正常情况下的调用链路差不多,详细咱们往下就能看到
void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (prev != null) {
prev.setWillCloseOrEnterPip(false);
//之前的状况是否为正在中止
final boolean wasStopping = prev.isState(STOPPING);
//设置状况为已暂停
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) {
//持续finish流程
prev = prev.completeFinishing("completePausedLocked");
} else if (prev.hasProcess()) {
//Configuration发生改变时可能会设置这个flag
if (prev.deferRelaunchUntilPaused) {
// Complete the deferred relaunch that was waiting for pause to complete.
//等候暂停完结后relaunch Activity
prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch);
} else if (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");
} else if (!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();
... //更新计算信息
}
//更新Activity可见性
mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
// 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;
}
}
能够看到,无论暂停成功与否,终究都会走到ActivityRecord.completeFinishing
办法中
/**
* 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) {
... //状况检查
final boolean isCurrentVisible = mVisibleRequested || isState(PAUSED);
if (isCurrentVisible) {
... //更新Activity可见性
}
boolean activityRemoved = false;
// 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.
final boolean 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");
} else if (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);
}
return activityRemoved ? null : this;
}
关于非锁屏状况且当时要毁掉的Activity
在前台的情况下,该Activity
可见而待康复的Activity
尚不可见,此刻优先完结待康复Activity
的resume
生命周期,等到之后闲暇再去处理待毁掉Activity
的destroy
生命周期
所以在面试中常问的Activity
从B
回来到A
的生命周期次序咱们从这儿就能够看出来,理解后咱们就不用去死记硬背了:
B.onPause
-> A.onRestart
-> A.onResume
-> B.onStop
-> B.onDestory
关于锁屏状况或者要毁掉的Activity
不在前台的情况下,由于不需求马上康复Activity
,所以可能会直接处理待毁掉Activity
的destroy
生命周期
咱们以第一种当时要毁掉的Activity
在前台的情况剖析,此刻会将这个Activity
增加到stop
列表中,并将状况设置为STOPPING
,之后回来到ActivityStack.completePauseLocked
办法中,持续履行resumeNext
作业
在resumeNext
中会调用RootWindowContainer.resumeFocusedStacksTopActivities
办法康复栈顶Activity
,由于这个办法之前现已在
Android源码剖析 – Activity发动流程(上) 中剖析过了,这儿就不再赘述了,咱们仍是将目光放在毁掉流程上
经过之前的文章,咱们知道康复Activity
会调用到ActivityThread.handleResumeActivity
办法,而当Activity
康复完毕后,此办法终究一行会向MessageQueue
增加一个IdleHandler
,关于IdleHandler
这儿就不再介绍了,这是每位Android
开发都应该了解的东西
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
r.nextIdle = mNewActivities;
mNewActivities = r;
Looper.myQueue().addIdleHandler(new Idler());
}
这儿的Idler
是ActivityThread
的一个内部类
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
...
if (a != null) {
mNewActivities = null;
IActivityTaskManager am = ActivityTaskManager.getService();
ActivityClientRecord prev;
//遍历整条ActivityClientRecord.nextIdle链,顺次调用ATMS.activityIdle
do {
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
...
return false;
}
}
这儿会遍历整个进程内一切的ActivityClientRecord
,并顺次调用ATMS.activityIdle
办法
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
...
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r == null) {
return;
}
mStackSupervisor.activityIdleInternal(r, false /* fromTimeout */,
false /* processPausingActivities */, config);
...
}
从ActivityRecord.Token
获取到ActivityRecord
,接着调用ActivityStackSupervisor.activityIdleInternal
办法
void activityIdleInternal(ActivityRecord r, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
...
// Atomically retrieve all of the other things to do.
processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
...
}
这儿咱们只需求要点重视processStoppingAndFinishingActivities
这一个办法,从办法名咱们也能看出来,它是用来处理Activity
stop
或destroy
的
/**
* Processes the activities to be stopped or destroyed. This should be called when the resumed
* activities are idle or drawn.
*/
private void processStoppingAndFinishingActivities(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);
final boolean 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);
}
}
final int 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();
}
}
}
final int numFinishingActivities = mFinishingActivities.size();
if (numFinishingActivities == 0) {
return;
}
// 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);
}
}
}
关于被标记为finishing
的Activity
,调用destroyIfPossible
办法毁掉
/**
* 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.
*/
boolean destroyIfPossible(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();
final boolean 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();
return false;
}
//设置finishing标记(之前设过了,这儿是重复设置)
makeFinishingLocked();
//马上履行Activity的毁掉流程
final boolean activityRemoved = destroyImmediately(true /* removeFromApp */,
"finish-imm:" + reason);
// 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();
}
return activityRemoved;
}
这儿做了终究的一些判别,然后调用destroyImmediately
办法,马上履行Activity的毁掉流程(这儿和上一个办法processStoppingAndFinishingActivities
中,待finish
列表的处理是相同的)
/**
* 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.
*/
boolean destroyImmediately(boolean removeFromApp, String reason) {
//现已被毁掉或正在被毁掉,直接回来
if (isState(DESTROYING, DESTROYED)) {
return false;
}
boolean removedFromHistory = false;
//整理作业
cleanUp(false /* cleanServices */, false /* setState */);
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");
}
}
configChangeFlags = 0;
return removedFromHistory;
}
scheduleTransaction
这个办法做了一些整理作业,重头戏在于调用了ClientLifecycleManager.scheduleTransaction
办法调度毁掉生命周期业务,接下来咱们就要点剖析这个业务的履行途径
scheduleTransaction
的调用链路咱们在 Android源码剖析 – Activity发动流程(下) 中现已剖析过了,这儿我就简单的标示一下流程:
ClientLifecycleManager.scheduleTransaction
->
ClientTransaction.schedule
->
ActivityThread.scheduleTransaction
->
ClientTransaction.preExecute
->
ActivityLifecycleItem.preExecute
->
ActivityThread.sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction)
->
TransactionExecutor.execute
->
TransactionExecutor.executeCallbacks
->
TransactionExecutor.executeLifecycleState
->
TransactionExecutor.cycleToPath
->
ActivityLifecycleItem.execute
->
ActivityLifecycleItem.postExecute
这儿的链路基本上和Activity
发动业务链路相差无几,甚至更短了(Activity
毁掉业务没有增加callback
),所以没看过我上篇文章的强烈推荐去看一下,这儿我就不再做剖析了
咱们从TransactionExecutor.cycleToPath
开端,之前咱们剖析过,咱们在业务中设置的ActivityLifecycleItem
代表了Activity
终究需求抵达履行的生命周期,而中心的那些过渡生命周期就由cycleToPath
办法推动履行,咱们现在的生命周期状况为ON_PAUSE
,而咱们的方针生命周期为ON_DESTROY
,中心还夹着一个ON_STOP
,所以这个办法会帮咱们履行ClientTransactionHandler.handleStopActivity
办法,也便是ActivityThread.handleStopActivity
办法
handleStopActivity
public void handleStopActivity(IBinder token, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest /* false */, String reason) {
final ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;
final StopInfo stopInfo = new StopInfo();
//履行onStop生命周期
performStopActivityInner(r, stopInfo, true /* saveState */, finalStateRequest,
reason);
//更新可见性
updateVisibility(r, false);
// Make sure any pending writes are now committed.
//保证一切大局使命都被处理完结
if (!r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
//记录Stop信息(不过在后续毁掉链路中好像并没有被用到)
stopInfo.setActivity(r);
stopInfo.setState(r.state);
stopInfo.setPersistentState(r.persistentState);
pendingActions.setStopInfo(stopInfo);
mSomeActivitiesChanged = true;
}
接下来的途径就和其他生命周期差不多了,大部分内容我都用注释标示了,我们顺着往下看就行了
/**
* 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.
*/
private void performStopActivityInner(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);
... //设置描述(Activity.onCreateDescription)
//回调Activity的onStop办法
callActivityOnStop(r, saveState, 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.
*/
private void callActivityOnStop(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
final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
&& !r.isPreHoneycomb();
//targetSdkVersion为Android P (Android 9)之前
final boolean isPreP = r.isPreP();
if (shouldSaveState && isPreP) {
callActivityOnSaveInstanceState(r);
}
try {
//履行stop生命周期
r.activity.performStop(r.mPreserveWindow, reason);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
//设置生命周期状况
r.setState(ON_STOP);
if (shouldSaveState && !isPreP) {
callActivityOnSaveInstanceState(r);
}
}
final void performStop(boolean preserveWindow, String reason) {
mDoReportFullyDrawn = false;
//Loader相关,详见https://developer.android.com/guide/components/loaders
mFragments.doLoaderStop(mChangingConfigurations /*retain*/);
// 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);
}
//FragmentManager分发stop状况
mFragments.dispatchStop();
mCalled = false;
//履行onStop回调
mInstrumentation.callActivityOnStop(this);
EventLogTags.writeWmOnStopCalled(mIdent, getComponentName().getClassName(), reason);
if (!mCalled) {
//必需要调用super.onStop办法
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStop()");
}
//释放Cursors
synchronized (mManagedCursors) {
final int N = mManagedCursors.size();
for (int i=0; i<N; i++) {
ManagedCursor mc = mManagedCursors.get(i);
if (!mc.mReleased) {
mc.mCursor.deactivate();
mc.mReleased = true;
}
}
}
mStopped = true;
//分发PostStopped事情,履行一切注册的ActivityLifecycleCallbacks的onActivityPostStopped回调
dispatchActivityPostStopped();
}
mResumed = false;
}
经过Instrumentation
履行onStop
回调
protected void onStop() {
//ActionBar动画
if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
//同享元素动画
mActivityTransitionState.onStop();
//分发PostStopped事情,履行一切注册的ActivityLifecycleCallbacks的onActivityPostStopped回调
dispatchActivityStopped();
mTranslucentCallback = null;
//super.onStop标示为已被履行
mCalled = true;
... //主动填充相关
mEnterAnimationComplete = false;
}
这样,一整个onStop
生命周期就履行完结了,终究还剩下个onDestroy
,根据之前写的业务调度链路,现在应该走到了DestroyActivityItem.execute
办法
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
client.handleDestroyActivity(token, mFinished, mConfigChanges,
false /* getNonConfigInstance */, "DestroyActivityItem");
}
能够看到,实际上就直接调用了ActivityThread.handleDestroyActivity
办法
handleDestroyActivity
public void handleDestroyActivity(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");
} 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.
//移除指定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;
}
Window
这块的处理我现在也不太了解,等以后我学习了WMS
那块再补吧
其他的和之前的套路相同,调用performDestroyActivity
办法履行毁掉Activity
/** Core implementation of activity destroy call. */
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
ActivityClientRecord r = mActivities.get(token);
Class<? extends Activity> activityClass = null;
if (r != null) {
activityClass = r.activity.getClass();
r.activity.mConfigChangeFlags |= configChanges;
if (finishing) {
r.activity.mFinished = true;
}
//假如没有被暂停则先履行pause生命周期
performPauseActivityIfNeeded(r, "destroy");
//假如没有被停职则先履行stop生命周期
if (!r.stopped) {
callActivityOnStop(r, false /* saveState */, "destroy");
}
if (getNonConfigInstance) {
... //getNonConfigInstance为false,这儿不履行
}
try {
r.activity.mCalled = false;
//履行onDestroy回调
mInstrumentation.callActivityOnDestroy(r.activity);
//必需要调用super.onDestroy办法
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) {
...
}
//设置生命周期状况
r.setState(ON_DESTROY);
}
//闲暇时整理资源
schedulePurgeIdler();
// updatePendingActivityConfiguration() reads from mActivities to update
// ActivityClientRecord which runs in a different thread. Protect modifications to
// mActivities to avoid race.
synchronized (mResourcesManager) {
mActivities.remove(token);
}
//严厉形式更新Activity计数器,与实际Activity数量对比,判别是否发生内存走漏
StrictMode.decrementExpectedActivityCount(activityClass);
return r;
}
经过Instrumentation
调用Activity.performDestroy
办法
final void performDestroy() {
//分发PreDestroyed事情,履行一切注册的ActivityLifecycleCallbacks的onActivityPreDestroyed回调
dispatchActivityPreDestroyed();
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy();
onDestroy();
EventLogTags.writeWmOnDestroyCalled(mIdent, getComponentName().getClassName(),
"performDestroy");
mFragments.doLoaderDestroy();
if (mVoiceInteractor != null) {
mVoiceInteractor.detachActivity();
}
//分发PostDestroyed事情,履行一切注册的ActivityLifecycleCallbacks的onActivityPostDestroyed回调
dispatchActivityPostDestroyed();
}
protected void onDestroy() {
//super.onDestroy标示为已被履行
mCalled = true;
... //主动填充相关
// dismiss any dialogs we are managing.
//封闭一切被办理的Dialog
if (mManagedDialogs != null) {
final int 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();
}
//分发Destroyed事情,履行一切注册的ActivityLifecycleCallbacks的onActivityDestroyed回调
dispatchActivityDestroyed();
//内容捕获服务
notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_STOP);
}
DestroyActivityItem
没有重写postExecute
办法,所以到此停止,Activity
整个毁掉流程就完毕了
Tips
咱们经过本篇文章的剖析,能够发现,触发Activity
毁掉后,onStop
和onDestroy
这两个生命周期回调的触发时机是不确认的,假如有需求需求在确认Activity
要被毁掉后马上履行,咱们能够在onPause
回调中调用Activity.isFinishing
办法判别mFinished
标志是否被置true
,假如为true
则能够判定这个Activity
将被毁掉
结尾
至此,Activity
的发动流程和毁掉流程咱们都剖析完了,后边应该暂时不会再写Activity
相关的源码剖析了
之后的一段时间,我可能会将我的精力投入到AIGC
的技能调研中,Android源码剖析
这一系列的后续更新可能会放慢,希望我们多多体谅