第一次啓動
07-31 14:58:26.179 2097 8344 I am_set_resumed_activity: [0,com.tencent.mobileqq/.activity.QQLSActivity,minimalResumeActivityLocked]
07-31 14:58:26.181 2097 8344 I am_pause_activity: [0,114682695,com.tencent.mobileqq/.activity.QQLSActivity,userLeaving=false]
07-31 14:58:26.186 2097 2114 I am_stop_activity: [0,250649096,com.tencent.mobileqq/.activity.SplashActivity]
07-31 14:58:26.274 17932 17932 I am_on_create_called: [0,com.tencent.mobileqq.activity.QQLSActivity,performCreate]
07-31 14:58:26.279 17932 17932 I am_on_start_called: [0,com.tencent.mobileqq.activity.QQLSActivity,handleStartActivity]
07-31 14:58:26.280 17932 17932 I am_on_resume_called: [0,com.tencent.mobileqq.activity.QQLSActivity,RESUME_ACTIVITY]
07-31 14:58:26.298 17932 17932 I am_on_paused_called: [0,com.tencent.mobileqq.activity.QQLSActivity,performPause]
....
第二次重新resume
07-31 14:58:26.307 2097 2114 I am_stop_activity: [0,114682695,com.tencent.mobileqq/.activity.QQLSActivity]
07-31 14:58:26.314 2097 2129 I am_set_resumed_activity: [0,com.tencent.mobileqq/.activity.QQLSActivity,resumeTopActivityInnerLocked]
07-31 14:58:26.322 2097 2129 I am_resume_activity: [0,114682695,62,com.tencent.mobileqq/.activity.QQLSActivity]
07-31 14:58:26.345 17932 17932 I am_on_stop_called: [0,com.tencent.mobileqq.activity.SplashActivity,STOP_ACTIVITY_ITEM]
07-31 14:58:26.409 17932 17932 I am_on_resume_called: [0,com.tencent.mobileqq.activity.QQLSActivity,RESUME_ACTIVITY]
07-31 14:58:26.179 2097 8344 I am_set_resumed_activity: [0,com.tencent.mobileqq/.activity.QQLSActivity,minimalResumeActivityLocked]
相關的堆棧流程
at com.android.server.am.ActivityRecord.completeResumeLocked(ActivityRecord.java:1905)
at com.android.server.am.ActivityStack.minimalResumeActivityLocked(ActivityStack.java:1319)
at com.android.server.am.ActivityStackSupervisor.realStartActivityLocked(ActivityStackSupervisor.java:1651)
at com.android.server.am.ActivityStackSupervisor.startSpecificActivityLocked(ActivityStackSupervisor.java:1746)
at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2886)
at com.android.server.am.ActivityStack.resumeTopActivityUncheckedLocked(ActivityStack.java:2386)
at com.android.server.am.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(ActivityStackSupervisor.java:2275)
at com.android.server.am.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1555)
at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:1270)
at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:923)
at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:558)
at com.android.server.am.ActivityStarter.startActivityMayWait(ActivityStarter.java:1154)
at com.android.server.am.ActivityStarter.execute(ActivityStarter.java:500)
at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:5651)
at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:5619)
at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:5610)
at android.app.IActivityManager$Stub.onTransact$startActivity$(IActivityManager.java:10231)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:122)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3599)
在frameworks/base/services/core/java/com/android/server/am/ActivityStack.java中
void minimalResumeActivityLocked(ActivityRecord r) {
...
r.setState(RESUMED, "minimalResumeActivityLocked");
r.completeResumeLocked();
mStackSupervisor.getLaunchTimeTracker().setLaunchTime(r);
...
}
////////
frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
void completeResumeLocked() {
.....
//恢復key分發
resumeKeyDispatchingLocked();
....
//此時canTurnScreenOn爲false,所以會走checkReadyForSleep這個方法
if (canTurnScreenOn()) {
mStackSupervisor.wakeUp("turnScreenOnFlag");
} else {
// If the screen is going to turn on because the caller explicitly requested it and
// the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
// pause and then resume again later, which will result in a double life-cycle event.
stack.checkReadyForSleep();
}
....
}
///////////////////
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
.....
void checkReadyForSleep() {
if (shouldSleepActivities() && goToSleepIfPossible(false /* shuttingDown */)) {
mStackSupervisor.checkReadyForSleepLocked(true /* allowDelay */);
}
}
//其中對應三個判斷變量
boolean shouldSleepActivities() {
final ActivityDisplay display = getDisplay();
// Do not sleep activities in this stack if we're marked as focused and the keyguard
// is in the process of going away.
if (mStackSupervisor.getFocusedStack() == this
&& mStackSupervisor.getKeyguardController().isKeyguardGoingAway()) {
return false;
}
////當前display & AMS 都處於sleep狀態,所以這個方法return true
return display != null ? display.isSleeping() : mService.isSleepingLocked();
}
////
/**
* Tries to put the activities in the stack to sleep.
*
* If the stack is not in a state where its activities can be put to sleep, this function will
* start any necessary actions to move the stack into such a state. It is expected that this
* function get called again when those actions complete.
*
* @param shuttingDown true when the called because the device is shutting down.
* @return true if the stack finished going to sleep, false if the stack only started the
* process of going to sleep (checkReadyForSleep will be called when that process finishes).
*/
boolean goToSleepIfPossible(boolean shuttingDown) {
....
boolean shouldSleep = true;
//如果當前有resume的Activity的界面則開始Pausing
if (mResumedActivity != null) {
// Still have something resumed; can't sleep until it is paused.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity);
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"Sleep => pause with userLeaving=false");
startPausingLocked(false, true, null, false);
shouldSleep = false ;
///如果Activity已是Pausing則繼續sleep
} else if (mPausingActivity != null) {
// Still waiting for something to pause; can't sleep yet.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity);
shouldSleep = false;
}
//按照流程傳遞進來的是false,所以會進入
if (!shuttingDown) {
if (containsActivityFromStack(mStackSupervisor.mStoppingActivities)) {
// Still need to tell some activities to stop; can't sleep yet.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to stop "
+ mStackSupervisor.mStoppingActivities.size() + " activities");
//檢測Message隊列中是否已經爲Idle ,如是則執行onStop操作
mStackSupervisor.scheduleIdleLocked();
shouldSleep = false;
}
if (containsActivityFromStack(mStackSupervisor.mGoingToSleepActivities)) {
// Still need to tell some activities to sleep; can't sleep yet.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still need to sleep "
+ mStackSupervisor.mGoingToSleepActivities.size() + " activities");
shouldSleep = false;
}
}
if (shouldSleep) {
goToSleep();
}
return shouldSleep;
}
}
如上第一次resume後馬上pause的原因是display.isSleeping() 和mService.isSleepingLocked()兩者都是true
後面再看一下從pause再resume的流程
當第一次的activity pause完成後,會觸發下次resumeFocusedStackTopActivityLocked
06-14 08:38:42.699 1087 7264 D ActivityManager: java.lang.Throwable
06-14 08:38:42.699 1087 7264 D ActivityManager: at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2429)
06-14 08:38:42.699 1087 7264 D ActivityManager: at com.android.server.am.ActivityStack.resumeTopActivityUncheckedLocked(ActivityStack.java:2386)
06-14 08:38:42.699 1087 7264 D ActivityManager: at com.android.server.am.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(ActivityStackSupervisor.java:2275)
06-14 08:38:42.699 1087 7264 D ActivityManager: at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:1688)
06-14 08:38:42.699 1087 7264 D ActivityManager: at com.android.server.am.ActivityStack.activityPausedLocked(ActivityStack.java:1606)
06-14 08:38:42.699 1087 7264 D ActivityManager: at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:8906)
06-14 08:38:42.699 1087 7264 D ActivityManager: at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:224)
06-14 08:38:42.699 1087 7264 D ActivityManager: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3599)
06-14 08:38:42.699 1087 7264 D ActivityManager: at android.os.Binder.execTransact(Binder.java:731)
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
activityPausedLocked的調用在如下幾個地方:
{moveToFrontAndResumeStateIfNeeded,startPausingLocked}--->
schedulePauseTimeout->H.PAUSE_TIMEOUT_MSG--->completePauseLocked
awakeFromSleepingLocked--->completePauseLocked
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
....
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
//第二次shouldSleepOrShutDownActivities爲false,進入到裏面執行
if (!topStack.shouldSleepOrShutDownActivities()) {
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
} else {
checkReadyForSleep();
ActivityRecord top = topStack.topRunningActivityLocked();
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.
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
}
}
.....
}
////topStack.shouldSleepOrShutDownActivities()這個方法中跟上面有些類似,此時shouldSleepActivities爲false,所以可以成功resume起來
boolean shouldSleepOrShutDownActivities() {
return shouldSleepActivities() || mService.isShuttingDownLocked();
}
////////////////////////
boolean shouldSleepActivities() {
final ActivityDisplay display = getDisplay();
// Do not sleep activities in this stack if we're marked as focused and the keyguard
// is in the process of going away.
if (mStackSupervisor.getFocusedStack() == this
&& mStackSupervisor.getKeyguardController().isKeyguardGoingAway()) {
return false;
}
return display != null ? display.isSleeping() : mService.isSleepingLocked();
}
再看一下display.isSleeping() 和mService.isSleepingLocked() 這兩個狀態的獲取流程
frameworks/base/services/core/java/com/android/server/am/ActivityDisplay.java
/**
86 * All of the stacks on this display. Order matters, topmost stack is in front of all other
87 * stacks, bottommost behind. Accessed directly by ActivityManager package classes. Any calls
88 * changing the list should also call {@link #onStackOrderChanged()}.
89 */
90 private final ArrayList<ActivityStack> mStacks = new ArrayList<>();
/** All tokens used to put activities on this stack to sleep (including mOffToken) */
97 final ArrayList<ActivityManagerInternal.SleepToken> mAllSleepTokens = new ArrayList<>();
........
boolean isSleeping() {
803 return mSleeping;
804 }
805
806 void setIsSleeping(boolean asleep) {
807 mSleeping = asleep;
808 }
boolean shouldSleep() {
737 return (mStacks.isEmpty() || !mAllSleepTokens.isEmpty())
738 && (mSupervisor.mService.mRunningVoice == null);
739 }
////////
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
goingToSleepLocked---> applySleepTokensLocked(false /* applyToStacks */)-->
void applySleepTokensLocked(boolean applyToStacks) {
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
// Set the sleeping state of the display.
final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
// 獲取是否可以sleep狀態,包含mStacks是否爲空或者mAllSleepTokens不爲空
final boolean displayShouldSleep = display.shouldSleep();
if (displayShouldSleep == display.isSleeping()) {
continue;
}
//設置是否睡眠狀態
display.setIsSleeping(displayShouldSleep);
if (!applyToStacks) {
continue;
}
......
}
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
SleepToken createSleepTokenLocked(String tag, int displayId) {
ActivityDisplay display = mActivityDisplays.get(displayId);
if (display == null) {
throw new IllegalArgumentException("Invalid display: " + displayId);
}
final SleepTokenImpl token = new SleepTokenImpl(tag, displayId);
mSleepTokens.add(token);
//將token添加到mAllSleepTokens這個列表中
display.mAllSleepTokens.add(token);
return token;
}
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
SleepToken acquireSleepToken(String tag, int displayId) {
synchronized (this) {
final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
updateSleepIfNeededLocked();
return token;
}
}
///////////
@VisibleForTesting
final class LocalService extends ActivityManagerInternal {
.....
@Override
public SleepToken acquireSleepToken(String tag, int displayId) {
Preconditions.checkNotNull(tag);
return ActivityManagerService.this.acquireSleepToken(tag, displayId);
}
.....
}
//其他地方通過類似這種方式調用
setKeyguardShown---->updateKeyguardSleepToken
keyguardGoingAway--->updateKeyguardSleepToken
handleOccludedChanged--->updateKeyguardSleepToken
frameworks/base/services/core/java/com/android/server/am/KeyguardController.java
private void updateKeyguardSleepToken() {
///當Keyguard或者AOD顯示的時候申請SleepToken,反之則釋放
if (mSleepToken == null && isKeyguardOrAodShowing(DEFAULT_DISPLAY)) {
mSleepToken = mService.acquireSleepToken("Keyguard", DEFAULT_DISPLAY);
} else if (mSleepToken != null && !isKeyguardOrAodShowing(DEFAULT_DISPLAY)) {
mSleepToken.release();
mSleepToken = null;
}
}
////
/**
* @return true if either Keyguard or AOD are showing, not going away, and not being occluded
* on the given display, false otherwise
*/
///displayId默認就爲DEFAULT_DISPLAY,所以需要mOccluded設爲false,isKeyguardOrAodShowing纔有可能返回true
boolean isKeyguardOrAodShowing(int displayId) {
return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway &&
(displayId == DEFAULT_DISPLAY ? !mOccluded : displayId == mSecondaryDisplayShowing);
}