還記得剛學(xué)Android那會坡脐,經(jīng)常會說起Activity的七大生命周期:
onCreate,onRestart,onStart,onResume,onPause,onStop,onDestroy泄私。
- Activity啟動的時候會執(zhí)行onCreate->onStart->onResume
- Activity被遮擋,但是依然可見時會執(zhí)行onPause
- Activity不可見時,會執(zhí)行onStop
- Activity在即將關(guān)閉的情況下會執(zhí)行onDestroy方法挖滤。
所以會有相當(dāng)一部分的Android開發(fā)者相信在Dialog彈出的時候Activity會執(zhí)行onPause的生命周期(Dialog彈出的時候Activity確實被遮擋,并且是可見狀態(tài)),那么到底是不是這樣浅役,我們可以做個demo驗證一下這種case:
package com.netease.myapplication;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG,"onCreate");
setContentView(R.layout.activity_main);
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG,"onRestart");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG,"onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG,"onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG,"onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG,"onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG,"onDestroy");
}
public void showDialog(View view) {
Dialog dialog = new Dialog(this);
TextView textView = new TextView(this);
textView.setText("這是一個彈窗");
dialog.addContentView(textView,new ViewGroup.LayoutParams(200,200));
dialog.show();
}
}
首先是建了一個Activity斩松,在七大生命周期上面都打出log, 然后寫一個Button的click方法觉既,主要就是為了彈出Dialog惧盹。那我們先看Activity創(chuàng)建的生命周期:
很簡單的一個過程,生命周期如下:
2021-01-23 16:42:57.413 10039-10039/com.netease.myapplication I/MainActivity: onCreate
2021-01-23 16:42:57.615 10039-10039/com.netease.myapplication I/MainActivity: onStart
2021-01-23 16:42:57.617 10039-10039/com.netease.myapplication I/MainActivity: onResume
嗯瞪讼,預(yù)料之中的結(jié)果钧椰。接下來我們再彈出Dialog試試:
就只是簡單的彈出一個Dialog(無視如此丑的彈窗),然后再看下生命周期:
發(fā)現(xiàn)Activity并沒有執(zhí)行任何的生命周期。既然不會調(diào)用生命周期符欠,那么以前聽說的彈出一個dialog會調(diào)用onPause的說法是從哪來的嫡霞?這個問題暫且不論,我們先來看下Dialog的過程:
Dialog dialog = new Dialog(this);
TextView textView = new TextView(this);
textView.setText("這是一個彈窗");
dialog.addContentView(textView,new ViewGroup.LayoutParams(200,200));
dialog.show();
我們可以看到Dialog主要做了三步操作:
創(chuàng)建一個Dialog對象
將View通過addContentView添加進(jìn)去
顯示Dialog希柿。
1. 首先第一步诊沪,創(chuàng)建一個Dialog對象
Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
if (createContextThemeWrapper) {
if (themeResId == Resources.ID_NULL) {
final TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);
themeResId = outValue.resourceId;
}
mContext = new ContextThemeWrapper(context, themeResId);
} else {
mContext = context;
}
//獲取WindowManagerService
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
//初始化Dialog的window
final Window w = new PhoneWindow(mContext);
mWindow = w;
//給Window設(shè)置callback
w.setCallback(this);
w.setOnWindowDismissedCallback(this);
w.setOnWindowSwipeDismissedCallback(() -> {
if (mCancelable) {
cancel();
}
});
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);
mListenersHandler = new ListenersHandler(this);
}
Dialog的構(gòu)造方法里面主要做了以下幾件事情:
- 創(chuàng)建Dialog的context
- 獲取WindowManagerImpl
- 初始化Dialog的window,設(shè)置callback曾撤,將WindowManagerImpl和Dialog的Window關(guān)聯(lián)起來(這里Dialog的window跟Activity的Window是不一致的端姚,所以在一旦Dialog彈出來的時候,觸摸事件就會被Dialog所在的Window所響應(yīng)挤悉,這里不做展開)
- 初始化ListenersHandler渐裸,Dialog的操作會通過這個Handler響應(yīng)。
2. Dialog的addContentView的操作:
public void addContentView(@NonNull View view, @Nullable ViewGroup.LayoutParams params) {
mWindow.addContentView(view, params);
}
會通過Window將當(dāng)前的View add進(jìn)去装悲,PhoneWindow主要是初始化了DecorView昏鹃,然后通過DecorView獲取了里面的mContentParent控件,再將View添加到mContentParent里面衅斩。
3. Dialog的show過程
public void show() {
if (mShowing) {
//做一個屏障盆顾,防止多次彈出彈窗
if (mDecor != null) {
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
}
mDecor.setVisibility(View.VISIBLE);
}
return;
}
mCanceled = false;
if (!mCreated) {
dispatchOnCreate(null);
} else {
// Fill the DecorView in on any configuration changes that
// may have occured while it was removed from the WindowManager.
final Configuration config = mContext.getResources().getConfiguration();
mWindow.getDecorView().dispatchConfigurationChanged(config);
}
//Dialog的onStart生命周期
onStart();
mDecor = mWindow.getDecorView();
...代碼省略...
//將DecorView加入到WindowManagerImpl中
mWindowManager.addView(mDecor, l);
...代碼省略...
//發(fā)送Show的消息
sendShowMessage();
}
show操作主要是將DecorView添加到WindowManagerImpl里面,然后調(diào)用WindowManagerGlobal畏梆,會創(chuàng)建ViewRootImpl的對象您宪,最后執(zhí)行ViewRootImpl的performMeasure,performLayout和performDraw方法奠涌,最終會將Dialog展示到屏幕上面宪巨。而最后一步就是執(zhí)行onShow的回調(diào)方法。沒有其他額外操作
至此Dialog的顯示過程全部結(jié)束溜畅,流程比較簡單捏卓。我們發(fā)現(xiàn)這里面并沒有涉及到ActivityManagerService。另外對于Activty啟動流程熟悉的也知道Activity的生命周期必須通過ActivityManagerService來分配調(diào)用。所以Dialog的顯示自然不可能會影響Activity的生命周期怠晴。
既然如此遥金,那么為什么會有這種說法呢?這事先從Activity的跳轉(zhuǎn)到第二個Activity說起蒜田,關(guān)于Activity的具體啟動流程這里不再贅述稿械,在經(jīng)過一系列的方法調(diào)用以后,最終會調(diào)用ActivityStarter#startActivity方法冲粤,那么就從這個方法開始說起:
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
int result = START_CANCELED;
final ActivityStack startedActivityStack;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
} finally {
final ActivityStack currentStack = r.getActivityStack();
startedActivityStack = currentStack != null ? currentStack : mTargetStack;
if (ActivityManager.isStartResultSuccessful(result)) {
if (startedActivityStack != null) {
// If there is no state change (e.g. a resumed activity is reparented to
// top of another display) to trigger a visibility/configuration checking,
// we have to update the configuration for changing to different display.
final ActivityRecord currentTop =
startedActivityStack.topRunningActivityLocked();
if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
mRootActivityContainer.ensureVisibilityAndConfig(
currentTop, currentTop.getDisplayId(),
true /* markFrozenIfConfigChanged */, false /* deferResume */);
}
}
} else {
...代碼省略...
}
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityProcessing(r, result, startedActivityStack);
return result;
}
這個方法主要做了兩件事情:
啟動下一個Activity (startActivityUnchecked)
根據(jù)實際情況設(shè)置其他Activity的狀態(tài)是否為不可見 (mRootActivityContainer.ensureVisibilityAndConfig)
我們先來看下第一步操作startActivityUnchecked美莫,這個方法接下來會調(diào)用RootActivityContainer#resumeFocusedStacksTopActivities方法(RootActivityContainer是Android10以后新增的類),然后調(diào)用ActivityStack#resumeTopActivityUncheckedLocked->調(diào)用ActivityStack#resumeTopActivityInnerLocked方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...代碼省略...
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, false);
}
...代碼省略...
return true;
}
這個方法非常的長梯捕,這里只需要關(guān)注startPausingLocked即可厢呵,這個方法首先會調(diào)用startPausingLocked方法pause掉當(dāng)前的Activity,然后后面會啟動下一個Activity傀顾。
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
...代碼省略...
if (prev.attachedToProcess()) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLogTags.writeAmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving);
mService.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.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
...代碼省略...
}
這段代碼就比較常見了襟铭,通過Android9.0 Activity啟動原理差異解析這篇文章可知,最終會指定PauseActivityItem的execute方法锣笨,然后執(zhí)行對應(yīng)的postExecute方法蝌矛。當(dāng)然這里采用的是Binder機制進(jìn)行調(diào)用,屬于異步的調(diào)用错英,但是result會直接返回入撒,正常情況下result都會是true。那么start結(jié)束以后椭岩,在回過頭看剛才說的RootActivityContainer#ensureVisibilityAndConfig方法,下面給出調(diào)用鏈
RootActivityContainer#ensureActivitiesVisible
ActivityDisplay#ensureActivitiesVisible
ActivityStack#ensureActivitiesVisibleLocked
final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
...代碼省略...
// If the top activity is not fullscreen, then we need to
// make sure any activities under it are now visible.
boolean aboveTop = top != null;
final boolean stackShouldBeVisible = shouldBeVisible(starting);
boolean behindFullscreenActivity = !stackShouldBeVisible;
boolean resumeNextActivity = isFocusable() && isInStackLocked(starting) == null;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
if (r.finishing) {
continue;
}
final boolean isTop = r == top;
if (aboveTop && !isTop) {
continue;
}
aboveTop = false;
// Check whether activity should be visible without Keyguard influence
final boolean visibleIgnoringKeyguard = r.shouldBeVisibleIgnoringKeyguard(
behindFullscreenActivity);
final boolean reallyVisible = r.shouldBeVisible(behindFullscreenActivity);
if (visibleIgnoringKeyguard) {
behindFullscreenActivity = updateBehindFullscreen(!stackShouldBeVisible,
behindFullscreenActivity, r);
}
if (reallyVisible) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
+ " finishing=" + r.finishing + " state=" + r.getState());
// First: if this is not the current activity being started, make
// sure it matches the current configuration.
if (r != starting && notifyClients) {
r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
true /* ignoreStopState */);
}
if (!r.attachedToProcess()) {
if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
resumeNextActivity, r)) {
if (activityNdx >= activities.size()) {
// Record may be removed if its process needs to restart.
activityNdx = activities.size() - 1;
} else {
resumeNextActivity = false;
}
}
} else if (r.visible) {
// If this activity is already visible, then there is nothing to do here.
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
"Skipping: already visible at " + r);
if (r.mClientVisibilityDeferred && notifyClients) {
r.makeClientVisible();
}
if (r.handleAlreadyVisible()) {
resumeNextActivity = false;
}
if (notifyClients) {
r.makeActiveIfNeeded(starting);
}
} else {
r.makeVisibleIfNeeded(starting, notifyClients);
}
// Aggregate current change flags.
configChanges |= r.configChangeFlags;
} else {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
+ " finishing=" + r.finishing + " state=" + r.getState()
+ " stackShouldBeVisible=" + stackShouldBeVisible
+ " behindFullscreenActivity=" + behindFullscreenActivity
+ " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
makeInvisible(r);
}
}
...代碼省略...
}
看代碼注釋茅逮,當(dāng)top Activity不是全屏Activity的時候,我們需要保證任何在這個非全屏Activity下面的Activity都是visible狀態(tài)判哥,所以對應(yīng)的ActivityRecord的visible為true献雅,那么什么作用呢?下面接著看客戶端這邊PauseActivityItem的postExecute方法
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mDontReport) {
return;
}
try {
// TODO(lifecycler): Use interface callback instead of AMS.
ActivityTaskManager.getService().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
execute方法就是將客戶端的Activity狀態(tài)設(shè)置成onPause塌计,而postExecute方法就是將服務(wù)端對應(yīng)的ActivityRecord的狀態(tài)設(shè)置成pause挺身。然后通過AMS調(diào)用到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);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
mService.mWindowManager.deferSurfaceLayout();
try {
completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
return;
} else {
EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
r.mUserId, 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);
finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false,
"activityPausedLocked");
}
}
}
}
mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
}
上面這段代碼執(zhí)行完畢以后,服務(wù)端的對應(yīng)的ActivityRecord也正是進(jìn)入了pause狀態(tài)锌仅,然后最頂上的Activity正式啟動章钾,會一次調(diào)用onCreate,onStart热芹,onResume贱傀。根據(jù)這篇文章可知,當(dāng)ActivityThread調(diào)用handleResumeActivity的時候伊脓,在最后會add一個IdleHandler用來stop上一個已經(jīng)處于pause狀態(tài)的Activity府寒。下面給出調(diào)用鏈:
ActivityTaskManagerService#activityIdle
ActivityStackSuperVisor#activityIdleInternalLocked
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
...代碼省略...
// Atomically retrieve all of the other things to do.
final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
true /* remove */, processPausingActivities);
NS = stops != null ? stops.size() : 0;
if ((NF = mFinishingActivities.size()) > 0) {
finishes = new ArrayList<>(mFinishingActivities);
mFinishingActivities.clear();
}
if (mStartingUsers.size() > 0) {
startingUsers = new ArrayList<>(mStartingUsers);
mStartingUsers.clear();
}
// Stop any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = 0; i < NS; i++) {
r = stops.get(i);
final ActivityStack stack = r.getActivityStack();
if (stack != null) {
if (r.finishing) {
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
"activityIdleInternalLocked");
} else {
stack.stopActivityLocked(r);
}
}
}
...代碼省略...
return r;
}
這里會獲取對應(yīng)的stops列表,然后對列表中的所有ActivityRecord進(jìn)行判斷,如果finishing狀態(tài)是true的那么執(zhí)行finish操作株搔,如果是false的就執(zhí)行stop操作剖淀。那么我們再來看下stops列表是如何獲取的
final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
true /* remove */, processPausingActivities);
調(diào)用的processStoppingActivitiesLocked方法獲取的,最終是從mStoppingActivities里面獲取的纤房。那么mStoppingActivities什么時候會把ActivityRecord add進(jìn)來呢祷蝌?搜索了一下這個對象的使用地方:
發(fā)現(xiàn)只有一處地方有add操作,那么點過去看下代碼:
private void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed,
String reason) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
EventLog.writeEvent(EventLogTags.AM_ADD_TO_STOPPING, r.mUserId,
System.identityHashCode(r), r.shortComponentName, reason);
mStackSupervisor.mStoppingActivities.add(r);
}
// If we already have a few activities waiting to stop, then give up
// on things going idle and start clearing them out. Or if r is the
// last of activity of the last task the stack will be empty and must
// be cleared immediately.
boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
|| (r.frontOfTask && mTaskHistory.size() <= 1);
if (scheduleIdle || forceIdle) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle="
+ forceIdle + "immediate=" + !idleDelayed);
if (!idleDelayed) {
mStackSupervisor.scheduleIdleLocked();
} else {
mStackSupervisor.scheduleIdleTimeoutLocked(r);
}
} else {
checkReadyForSleep();
}
}
這個方法判斷當(dāng)前mStoppingActivities列表里面是否包含指定的ActivityRecord帆卓,如果不包含那就添加進(jìn)來,很明顯了只要執(zhí)行了這段代碼米丘,那么mStoppingActivities肯定就會添加這個ActivityRecord剑令,然后必然會在前面ActivityStackSuperVisor#activityIdleInternalLocked的方法中執(zhí)行對應(yīng)的stop方法。那么接下來就看什么時候這個addToStopping執(zhí)行了拄查。我們可以發(fā)現(xiàn)下面這個方法:
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
...代碼省略吁津。。堕扶。
if (prev != null) {
prev.setWillCloseOrEnterPip(false);
final boolean wasStopping = prev.isState(STOPPING);
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
"completePausedLocked");
} else if (prev.hasProcess()) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
+ " wasStopping=" + wasStopping + " visible=" + prev.visible);
if (prev.deferRelaunchUntilPaused) {
// Complete the deferred relaunch that was waiting for pause to complete.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
prev.relaunchActivityLocked(false /* andResume */,
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.visible || 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.
addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */,
"completePauseLocked");
}
} 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;
}
...代碼省略...
}
- 首先prev并沒有調(diào)用finish方法碍脏, 所以finishing狀態(tài)肯定是false。
- 然后根據(jù)淺談APP的回收和重啟機制可知稍算,只有在系統(tǒng)回收當(dāng)前Activity的時候
prev.hasProcess()才會是false典尾, 所以正常情況下這個值必然是true。 - prev并沒有重新啟動糊探,當(dāng)前狀態(tài)也不是stopping钾埂,所以就看最后一個判斷邏輯。
- shouldSleepOrShutDownActivities()方法判斷當(dāng)前手機是否關(guān)機或者鎖屏科平,很明顯這里的判斷是false
- 而一旦將要啟動的Activity是非全屏的Activity的時候褥紫,prev.visible會是true,所以(!prev.visible || shouldSleepOrShutDownActivities())這個條件不滿足瞪慧,也就是不會指定addToStopping方法髓考,那么根據(jù)上面的結(jié)論,prev對應(yīng)的Activity也就不會執(zhí)行onStop方法了弃酌。
總結(jié)
所以Dialog彈出時是不會影響Activity生命周期的氨菇,Activity也就不會進(jìn)入所謂的onPause狀態(tài)。所謂的可見狀態(tài)下進(jìn)入onPause其實說的是透明背景的Activity或者是Dialog主題的Activity彈出來的時候矢腻,那么前一個頁面確實只會調(diào)用onPause方法门驾。