Activity相关学习-启动(5)-启动流程总结之启动逻辑
2019-01-13 本文已影响0人
weiinter105
前言
前面将复用逻辑大致介绍完成了,下面介绍在startActivityUnchecked中剩下的启动逻辑
step 1:
1360 if (mStartActivity.packageName == null) {
1361 final ActivityStack sourceStack = mStartActivity.resultTo != null
1362 ? mStartActivity.resultTo.getStack() : null;
1363 if (sourceStack != null) {
1364 sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
1365 mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
1366 null /* data */);
1367 }
1368 ActivityOptions.abort(mOptions);
1369 return START_CLASS_NOT_FOUND;
1370 }
1371
1372 // If the activity being launched is the same as the one currently at the top, then
1373 // we need to check if it should only be launched once.
1374 final ActivityStack topStack = mSupervisor.mFocusedStack;
1375 final ActivityRecord topFocused = topStack.getTopActivity();
1376 final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
1377 final boolean dontStart = top != null && mStartActivity.resultTo == null
1378 && top.realActivity.equals(mStartActivity.realActivity)
1379 && top.userId == mStartActivity.userId
1380 && top.app != null && top.app.thread != null
1381 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
1382 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
1383 if (dontStart) { //dontStart条件判断
1384 // For paranoia, make sure we have correctly resumed the top activity.
1385 topStack.mLastPausedActivity = null;
1386 if (mDoResume) {
1387 mSupervisor.resumeFocusedStackTopActivityLocked(); //以防万一,对top Activity再走一遍resume的流程,当然如果其已经处在resumed状态就不会再走一遍了
1388 }
1389 ActivityOptions.abort(mOptions);
1390 if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
1391 // We don't need to start a new activity, and the client said not to do
1392 // anything if that is the case, so this is it!
1393 return START_RETURN_INTENT_TO_CALLER;
1394 }
1395
1396 deliverNewIntent(top);
1397
1398 // Don't use mStartActivity.task to show the toast. We're not starting a new activity
1399 // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
1400 mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
1401 preferredLaunchDisplayId, topStack);
1402
1403 return START_DELIVERED_TO_TOP;
1404 }
step 2:
复用不复用task都可能走到这里,准备好正确的task,stack,保证在前台,将ActivityRecord放到相应的task的history中,并为其赋值类型:
1406 boolean newTask = false;
1407 final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1408 ? mSourceRecord.getTask() : null;
1409
1410 // Should this be considered a new task?
1411 int result = START_SUCCESS;
1412 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
1413 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
1414 newTask = true;
1415 String packageName= mService.mContext.getPackageName();
1416 if (mPerf != null) {
1417 mPerf.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST,
1418 packageName, -1, BoostFramework.Launch.BOOST_V1);
1419 }
1420 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
1421 } else if (mSourceRecord != null) {
1422 result = setTaskFromSourceRecord();
1423 } else if (mInTask != null) {
1424 result = setTaskFromInTask();
1425 } else {
1426 // This not being started from an existing activity, and not part of a new task...
1427 // just put it in the top task, though these days this case should never happen.
1428 setTaskToCurrentTopOrCreateNewTask();
1429 }
ActivityStarter#setTaskFromSourceRecord
复用不复用task都可能走到这里;从sourceRecord中得到正确的task,stack,保证在前台,将ActivityRecord放到相应的task的history中,并为其赋值类型
private int setTaskFromSourceRecord() {
if (mService.getLockTaskController().isLockTaskModeViolation(mSourceRecord.getTask())) {
Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
String packageName= mService.mContext.getPackageName();
final TaskRecord sourceTask = mSourceRecord.getTask();
final ActivityStack sourceStack = mSourceRecord.getStack();
// We only want to allow changing stack in two cases: change stack的两种情况
// 1. If the target task is not the top one. Otherwise we would move the launching task to
// the other side, rather than show two side by side.
// 2. If activity is not allowed on target display.
final int targetDisplayId = mTargetStack != null ? mTargetStack.mDisplayId
: sourceStack.mDisplayId;
final boolean moveStackAllowed = sourceStack.topTask() != sourceTask
|| !mStartActivity.canBeLaunchedOnDisplay(targetDisplayId);
if (moveStackAllowed) {
mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.getTask(),
mOptions); //Returns the right stack to use for launching factoring in all the input parameters.
// If target stack is not found now - we can't just rely on the source stack, as it may
// be not suitable. Let's check other displays.
if (mTargetStack == null && targetDisplayId != sourceStack.mDisplayId) {
// Can't use target display, lets find a stack on the source display.
mTargetStack = mService.mStackSupervisor.getValidLaunchStackOnDisplay(
sourceStack.mDisplayId, mStartActivity);
}
if (mTargetStack == null) {
// There are no suitable stacks on the target and source display(s). Look on all
// displays.
mTargetStack = mService.mStackSupervisor.getNextValidLaunchStackLocked(
mStartActivity, -1 /* currentFocus */);
}
}
if (mTargetStack == null) {
mTargetStack = sourceStack; //设置待启动Activity的stack
} else if (mTargetStack != sourceStack) {
sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
DEFER_RESUME, "launchToSide"); //将task移到mTargetStack中
}
final TaskRecord topTask = mTargetStack.topTask();
if (topTask != sourceTask && !mAvoidMoveToFront) {
mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
mStartActivity.appTimeTracker, "sourceTaskToFront"); //保证正确的task,stack在前台
} else if (mDoResume) {
mTargetStack.moveToFront("sourceStackToFront"); //保证正确的stack在前台
}
if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0) {
// In this case, we are adding the activity to an existing task, but the caller has
// asked to clear that task if the activity is already running.
ActivityRecord top = sourceTask.performClearTaskLocked(mStartActivity, mLaunchFlags);
mKeepCurTransition = true;
if (top != null) {
ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTask());
deliverNewIntent(top);
// For paranoia, make sure we have correctly resumed the top activity.
mTargetStack.mLastPausedActivity = null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
ActivityOptions.abort(mOptions);
return START_DELIVERED_TO_TOP;
}
} else if (!mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
// In this case, we are launching an activity in our own task that may already be
// running somewhere in the history, and we want to shuffle it to the front of the
// stack if so.
final ActivityRecord top = sourceTask.findActivityInHistoryLocked(mStartActivity);
if (top != null) {
final TaskRecord task = top.getTask();
task.moveActivityToFrontLocked(top);
top.updateOptionsLocked(mOptions);
ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, task);
deliverNewIntent(top);
mTargetStack.mLastPausedActivity = null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
return START_DELIVERED_TO_TOP;
}
}
// An existing activity is starting this new activity, so we want to keep the new one in
// the same task as the one that is starting it.
addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
//将ActivityRecord加入到相应task记录中并为Activity类型赋值
if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ " in existing task " + mStartActivity.getTask() + " from source " + mSourceRecord);
return START_SUCCESS;
}
addOrReparentStartingActivity相关逻辑
private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
parent.addActivityToTop(mStartActivity);
} else {
mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
}
}
void addActivityToTop(ActivityRecord r) {
addActivityAtIndex(mActivities.size(), r);
}
/**
* Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
* be in the current task or unparented to any task.
*/
void addActivityAtIndex(int index, ActivityRecord r) {
TaskRecord task = r.getTask();
if (task != null && task != this) {
throw new IllegalArgumentException("Can not add r=" + " to task=" + this
+ " current parent=" + task);
}
r.setTask(this);
// Remove r first, and if it wasn't already in the list and it's fullscreen, count it.
if (!mActivities.remove(r) && r.fullscreen) {
// Was not previously in list.
numFullscreen++;
}
// Only set this based on the first activity
if (mActivities.isEmpty()) {
if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
// Normally non-standard activity type for the activity record will be set when the
// object is created, however we delay setting the standard application type until
// this point so that the task can set the type for additional activities added in
// the else condition below.
r.setActivityType(ACTIVITY_TYPE_STANDARD);
}
setActivityType(r.getActivityType());
isPersistable = r.isPersistable();
mCallingUid = r.launchedFromUid;
mCallingPackage = r.launchedFromPackage;
// Clamp to [1, max].
maxRecents = Math.min(Math.max(r.info.maxRecents, 1),
ActivityManager.getMaxAppRecentsLimitStatic());
} else {
// Otherwise make all added activities match this one.
r.setActivityType(getActivityType());
}
final int size = mActivities.size();
if (index == size && size > 0) {
final ActivityRecord top = mActivities.get(size - 1);
if (top.mTaskOverlay) {
// Place below the task overlay activity since the overlay activity should always
// be on top.
index--;
}
}
index = Math.min(size, index);
mActivities.add(index, r);
updateEffectiveIntent();
if (r.isPersistable()) {
mService.notifyTaskPersisterLocked(this, false);
}
// Sync. with window manager
updateOverrideConfigurationFromLaunchBounds();
final AppWindowContainerController appController = r.getWindowContainerController();
if (appController != null) {
// Only attempt to move in WM if the child has a controller. It is possible we haven't
// created controller for the activity we are starting yet.
mWindowContainerController.positionChildAt(appController, index);
}
// Make sure the list of display UID whitelists is updated
// now that this record is in a new task.
mService.mStackSupervisor.updateUIDsPresentOnDisplay();
}
ActivityStarter#setTaskFromReuseOrCreateNewTask
newtask = true且要start的Activity有NEW_TASK flag时会走到这里;这里目前看来只是创建stack,创建task,添加task到stack,stack移到前台
private int setTaskFromReuseOrCreateNewTask(
TaskRecord taskToAffiliate, ActivityStack topStack) {
mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
//返回启动Activity所在的stack
// Do no move the target stack to front yet, as we might bail if
// isLockTaskModeViolation fails below.
if (mReuseTask == null) {
final TaskRecord task = mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
mOptions); //创建task并放到stack中
addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask"); //将Activity放到task的history中,并赋值Activity的类型
updateBounds(mStartActivity.getTask(), mLaunchParams.mBounds);
if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ " in new task " + mStartActivity.getTask());
} else {
addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
}
if (taskToAffiliate != null) {
mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
}
if (mService.getLockTaskController().isLockTaskModeViolation(mStartActivity.getTask())) {
Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
if (mDoResume) {
mTargetStack.moveToFront("reuseOrNewTask"); //将stack移到前面
}
return START_SUCCESS;
}
computeStackFocus
private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, int launchFlags,
ActivityOptions aOptions) {
final TaskRecord task = r.getTask();
ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
//返回启动Activity所在的stack(已存在或者新创建都有可能)
if (stack != null) {
return stack;
}
final ActivityStack currentStack = task != null ? task.getStack() : null;
if (currentStack != null) {
if (mSupervisor.mFocusedStack != currentStack) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Setting " + "focused stack to r=" + r
+ " task=" + task);
} else {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Focused stack already="
+ mSupervisor.mFocusedStack);
}
return currentStack;
}
if (canLaunchIntoFocusedStack(r, newTask)) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
return mSupervisor.mFocusedStack;
}
if (mPreferredDisplayId != DEFAULT_DISPLAY) {
// Try to put the activity in a stack on a secondary display.
stack = mSupervisor.getValidLaunchStackOnDisplay(mPreferredDisplayId, r);
if (stack == null) {
// If source display is not suitable - look for topmost valid stack in the system.
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Can't launch on mPreferredDisplayId="
+ mPreferredDisplayId + ", looking on all displays.");
stack = mSupervisor.getNextValidLaunchStackLocked(r, mPreferredDisplayId);
}
}
if (stack == null) {
// We first try to put the task in the first dynamic stack on home display.
final ActivityDisplay display = mSupervisor.getDefaultDisplay();
for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
stack = display.getChildAt(stackNdx);
if (!stack.isOnHomeDisplay()) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Setting focused stack=" + stack);
return stack;
}
}
// If there is no suitable dynamic stack then we figure out which static stack to use.
stack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
}
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
+ r + " stackId=" + stack.mStackId);
return stack;
}
ActivityStarter#setTaskFromInTask
针对inTask参数的处理
private int setTaskFromInTask() {
// The caller is asking that the new activity be started in an explicit
// task it has provided to us.
if (mService.getLockTaskController().isLockTaskModeViolation(mInTask)) {
Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
mTargetStack = mInTask.getStack();
// Check whether we should actually launch the new activity in to the task,
// or just reuse the current activity on top.
ActivityRecord top = mInTask.getTopActivity();
if (top != null && top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId) {
if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) {
mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
mStartActivity.appTimeTracker, "inTaskToFront");
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and the client said not to do
// anything if that is the case, so this is it!
return START_RETURN_INTENT_TO_CALLER;
}
deliverNewIntent(top);
return START_DELIVERED_TO_TOP;
}
}
if (!mAddingToTask) {
mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions,
mStartActivity.appTimeTracker, "inTaskToFront");
// We don't actually want to have this activity added to the task, so just
// stop here but still tell the caller that we consumed the intent.
ActivityOptions.abort(mOptions);
return START_TASK_TO_FRONT;
}
if (!mLaunchParams.mBounds.isEmpty()) {
// TODO: Shouldn't we already know what stack to use by the time we get here?
ActivityStack stack = mSupervisor.getLaunchStack(null, null, mInTask, ON_TOP);
if (stack != mInTask.getStack()) {
mInTask.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE,
DEFER_RESUME, "inTaskToFront");
mTargetStack = mInTask.getStack();
}
updateBounds(mInTask, mLaunchParams.mBounds);
}
mTargetStack.moveTaskToFrontLocked(
mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ " in explicit task " + mStartActivity.getTask());
return START_SUCCESS;
}
step 3:
mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
if (newTask) {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
mStartActivity.getTask().taskId);
}
ActivityStack.logStartActivity(
EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
mTargetStack.mLastPausedActivity = null;
mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
ActivityStack#startActivityLocked
为要启动的Activity设置,Activity创建相应的AppWindowContainerController(其中创建AppWindowToken),并将其放到相应task的top;做一些准备工作,为task中的Activity设置frontTask属性;做一些动画切换的准备工作
void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
boolean newTask, boolean keepCurTransition, ActivityOptions options) {
TaskRecord rTask = r.getTask();
final int taskId = rTask.taskId;
// mLaunchTaskBehind tasks get placed at the back of the task stack.
if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
// Last activity in task had been removed or ActivityManagerService is reusing task.
// Insert or replace.
// Might not even be in.
insertTaskAtTop(rTask, r);
}
TaskRecord task = null;
if (!newTask) {
// If starting in an existing task, find where that is...
boolean startIt = true;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
task = mTaskHistory.get(taskNdx);
if (task.getTopActivity() == null) {
// All activities in task are finishing.
continue;
}
if (task == rTask) {
// Here it is! Now, if this is not yet visible to the
// user, then just add it without starting; it will
// get started when the user navigates back to it.
if (!startIt) {
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
+ task, new RuntimeException("here").fillInStackTrace());
r.createWindowContainer();
ActivityOptions.abort(options);
return;
}
break;
} else if (task.numFullscreen > 0) {
startIt = false;
}
}
}
// Place a new activity at top of stack, so it is next to interact with the user.
// If we are not placing the new activity frontmost, we do not want to deliver the
// onUserLeaving callback to the actual frontmost activity
final TaskRecord activityTask = r.getTask();
if (task == activityTask && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) { //mTaskHistory.size() - 1 为当前stack的top task
mStackSupervisor.mUserLeaving = false;
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"startActivity() behind front, mUserLeaving=false");
}
task = activityTask;
// Slot the activity into the history stack and proceed
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
new RuntimeException("here").fillInStackTrace());
// TODO: Need to investigate if it is okay for the controller to already be created by the
// time we get to this point. I think it is, but need to double check.
// Use test in b/34179495 to trace the call path.
if (r.getWindowContainerController() == null) {
r.createWindowContainer(); //为Activity创建相应的AppWindowContainerController,并将Activity放到相应task的top
}
task.setFrontOfTask(); //为相应task设置frontTask属性
if (mActivityTrigger != null) {
mActivityTrigger.activityStartTrigger(r.intent, r.info, r.appInfo, r.fullscreen);
}
if (mActivityPluginDelegate != null && getWindowingMode() != WINDOWING_MODE_UNDEFINED) {
mActivityPluginDelegate.activityInvokeNotification
(r.appInfo.packageName, getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
}
//做切换动画的一些准备工作
if (!isActivityTypeHome() || numActivities() > 0) {
// We want to show the starting preview window if we are
// switching to a new task, or the next activity's process is
// not currently running.
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare open transition: starting " + r);
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
mStackSupervisor.mNoAnimActivities.add(r);
} else {
int transit = TRANSIT_ACTIVITY_OPEN;
if (newTask) {
if (r.mLaunchTaskBehind) {
transit = TRANSIT_TASK_OPEN_BEHIND;
} else {
// If a new task is being launched, then mark the existing top activity as
// supporting picture-in-picture while pausing only if the starting activity
// would not be considered an overlay on top of the current activity
// (eg. not fullscreen, or the assistant)
if (canEnterPipOnTaskSwitch(focusedTopActivity,
null /* toFrontTask */, r, options)) {
focusedTopActivity.supportsEnterPipOnTaskSwitch = true;
}
transit = TRANSIT_TASK_OPEN;
}
}
mWindowManager.prepareAppTransition(transit, keepCurTransition);
mStackSupervisor.mNoAnimActivities.remove(r);
}
boolean doShow = true;
if (newTask) {
// Even though this activity is starting fresh, we still need
// to reset it to make sure we apply affinities to move any
// existing activities from other tasks in to it.
// If the caller has requested that the target task be
// reset, then do so.
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
resetTaskIfNeededLocked(r, r);
doShow = topRunningNonDelayedActivityLocked(null) == r;
}
} else if (options != null && options.getAnimationType()
== ActivityOptions.ANIM_SCENE_TRANSITION) {
doShow = false;
}
newTask = newTask;
if (r.mLaunchTaskBehind) {
// Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
// tell WindowManager that r is visible even though it is at the back of the stack.
r.setVisibility(true);
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); //设置相应Activity的visible状态
} else if (SHOW_APP_STARTING_PREVIEW && doShow) {
// Figure out if we are transitioning from another activity that is
// "has the same starting icon" as the next one. This allows the
// window manager to keep the previous window it had previously
// created, if it still had one.
TaskRecord prevTask = r.getTask();
ActivityRecord prev = prevTask.topRunningActivityWithStartingWindowLocked();
if (prev != null) {
// We don't want to reuse the previous starting preview if:
// (1) The current activity is in a different task.
if (prev.getTask() != prevTask) {
prev = null;
}
// (2) The current activity is already displayed.
else if (prev.nowVisible) {
prev = null;
}
}
r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
}
} else {
// If this is the first activity, don't do any fancy animations,
// because there is nothing for it to animate on top of.
ActivityOptions.abort(options);
}
}
step 4:
真正启动流程,pause->resume->stop等等操作
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
// If the activity is not focusable, we can't resume it, but still would like to
// make sure it becomes visible as it starts (this will also trigger entry
// animation). An example of this are PIP activities.
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mService.mWindowManager.executeAppTransition();
} else {
// If the target stack was not previously focusable (previous top running activity
// on that stack was not visible) then any prior calls to move the stack to the
// will not update the focused stack. If starting the new activity now allows the
// task stack to be focusable, then ensure that we now update the focused stack
// accordingly.
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked"); //如果当前stack状态不对,移到前台,个人理解,这个只是一个保险作用
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions); //执行resumeFocusedStackTopActivityLocked的流程
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
}
mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
preferredLaunchDisplayId, mTargetStack);
return START_SUCCESS;
}
ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
2228 boolean resumeFocusedStackTopActivityLocked(
2229 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
2230
2231 if (!readyToResume()) {
2232 return false;
2233 }
2234
2235 if (targetStack != null && isFocusedStack(targetStack)) {
2236 return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); //如果所在ActivityStack已经focus了,直接resume该target Activity
//传的是startActivity啊
2237 }
2238
2239 final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); //否则resume focus stack的top Activity
2240 if (r == null || !r.isState(RESUMED)) {
2241 mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
2242 } else if (r.isState(RESUMED)) {
2243 // Kick off any lingering app transitions form the MoveTaskToFront operation.
2244 mFocusedStack.executeAppTransition(targetOptions);
2245 }
2246
2247 return false;
2248 }
2286 /**
2287 * Ensure that the top activity in the stack is resumed.
2288 *
2289 * @param prev The previously resumed activity, for when in the process
2290 * of pausing; can be null to call from elsewhere.
2291 * @param options Activity options.
2292 *
2293 * @return Returns true if something is being resumed, or false if
2294 * nothing happened.
2295 *
2296 * NOTE: It is not safe to call this method directly as it can cause an activity in a
2297 * non-focused stack to be resumed.
2298 * Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked} to resume the
2299 * right activity for the current system state.
2300 */
2301 @GuardedBy("mService")
2302 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
//但这里prev为何代表上一个resumed的Activity呢?注意这里是针对completePauseLocked中的第二次调用而言的
//mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null); 这里prev为刚刚paused的Activity
2303 if (mStackSupervisor.inResumeTopActivity) {
2304 // Don't even start recursing.
2305 return false;
2306 }
2307
2308 boolean result = false;
2309 try {
2310 // Protect against recursion.
2311 mStackSupervisor.inResumeTopActivity = true;
2312 result = resumeTopActivityInnerLocked(prev, options);
2313
2314 // When resuming the top activity, it may be necessary to pause the top activity (for
2315 // example, returning to the lock screen. We suppress the normal pause logic in
2316 // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
2317 // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
2318 // to ensure any necessary pause logic occurs. In the case where the Activity will be
2319 // shown regardless of the lock screen, the call to
2320 // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
2321 final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
2322 if (next == null || !next.canTurnScreenOn()) {
2323 checkReadyForSleep();
2324 }
2325 } finally {
2326 mStackSupervisor.inResumeTopActivity = false;
2327 }
2328
2329 return result;
2330 }
2349 @GuardedBy("mService")
2350 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
2351 if (!mService.mBooting && !mService.mBooted) {
2352 // Not ready yet!
2353 return false;
2354 }
2355
2356 // Find the next top-most activity to resume in this stack that is not finishing and is
2357 // focusable. If it is not focusable, we will fall into the case below to resume the
2358 // top activity in the next focusable task.
2359 final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */); //next为要resume的Activity
2360
2361 final boolean hasRunningActivity = next != null;
2362
2363 // TODO: Maybe this entire condition can get removed?
2364 if (hasRunningActivity && !isAttached()) {
2365 return false;
2366 }
2367
2368 mStackSupervisor.cancelInitializingActivities();
2369
2370 // Remember how we'll process this pause/resume situation, and ensure
2371 // that the state is reset however we wind up proceeding.
2372 boolean userLeaving = mStackSupervisor.mUserLeaving;
2373 mStackSupervisor.mUserLeaving = false;
2374
2375 if (!hasRunningActivity) {
2376 // There are no activities left in the stack, let's look somewhere else.
2377 return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
2378 }
2379
2380 next.delayedResume = false;
2381
2382 // If the top activity is the resumed one, nothing to do.
2383 if (mResumedActivity == next && next.isState(RESUMED)
2384 && mStackSupervisor.allResumedActivitiesComplete()) { //要resume的已经处于resumed状态
2385 // Make sure we have executed any pending transitions, since there
2386 // should be nothing left to do at this point.
2387 executeAppTransition(options);
2388 if (DEBUG_STATES) Slog.d(TAG_STATES,
2389 "resumeTopActivityLocked: Top activity resumed " + next);
2390 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2391 return false;
2392 }
2393
2394 // If we are sleeping, and there is no resumed activity, and the top
2395 // activity is paused, well that is the state we want.
2396 if (shouldSleepOrShutDownActivities()
2397 && mLastPausedActivity == next
2398 && mStackSupervisor.allPausedActivitiesComplete()) {
2399 // Make sure we have executed any pending transitions, since there
2400 // should be nothing left to do at this point.
2401 executeAppTransition(options);
2402 if (DEBUG_STATES) Slog.d(TAG_STATES,
2403 "resumeTopActivityLocked: Going to sleep and all paused");
2404 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2405 return false;
2406 }
2407
2408 // Make sure that the user who owns this activity is started. If not,
2409 // we will just leave it as is because someone should be bringing
2410 // another user's activities to the top of the stack.
2411 if (!mService.mUserController.hasStartedUserState(next.userId)) {
2412 Slog.w(TAG, "Skipping resume of top activity " + next
2413 + ": user " + next.userId + " is stopped");
2414 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2415 return false;
2416 }
2417 //上面都是一些不走resume的判断
2418 // The activity may be waiting for stop, but that is no longer
2419 // appropriate for it.
2420 mStackSupervisor.mStoppingActivities.remove(next);
2421 mStackSupervisor.mGoingToSleepActivities.remove(next);
2422 next.sleeping = false;
2423 mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
2424 next.launching = true;
2425 //要start了,从相关的队列中remove
2426 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
2427
2428 if (mActivityTrigger != null) {
2429 mActivityTrigger.activityResumeTrigger(next.intent, next.info, next.appInfo,
2430 next.fullscreen);
2431 }
2432
2433 if (mActivityPluginDelegate != null && getWindowingMode() != WINDOWING_MODE_UNDEFINED) {
2434 mActivityPluginDelegate.activityInvokeNotification
2435 (next.appInfo.packageName, getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
2436 }
2437
2438 // If we are currently pausing an activity, then don't do anything
2439 // until that is done.
2440 if (!mStackSupervisor.allPausedActivitiesComplete()) {
2441 if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
2442 "resumeTopActivityLocked: Skip resume: some activity pausing.");
2443 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); //直到所有Activity都处于isState(PAUSED, STOPPED, STOPPING)状态才会继续往下走
2444 return false;
2445 }
2446
2447 mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
2462
2463 boolean lastResumedCanPip = false;
2464 ActivityRecord lastResumed = null;
2465 final ActivityStack lastFocusedStack = mStackSupervisor.getLastStack();
2466 if (lastFocusedStack != null && lastFocusedStack != this) {
2467 // So, why aren't we using prev here??? See the param comment on the method. prev doesn't
2468 // represent the last resumed activity. However, the last focus stack does if it isn't null.
2469 lastResumed = lastFocusedStack.mResumedActivity;
2470 if (userLeaving && inMultiWindowMode() && lastFocusedStack.shouldBeVisible(next)) {
2471 // The user isn't leaving if this stack is the multi-window mode and the last
2472 // focused stack should still be visible.
2473 if(DEBUG_USER_LEAVING) Slog.i(TAG_USER_LEAVING, "Overriding userLeaving to false"
2474 + " next=" + next + " lastResumed=" + lastResumed);
2475 userLeaving = false;
2476 }
2477 lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
2478 "resumeTopActivity", userLeaving /* beforeStopping */);
2479 }
2480 // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity
2481 // to be paused, while at the same time resuming the new resume activity only if the
2482 // previous activity can't go into Pip since we want to give Pip activities a chance to
2483 // enter Pip before resuming the next activity.
2484 final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
2485 && !lastResumedCanPip; //resumeWhilePausing代表在pausing的过程中就执行resumed的操作
2486
2487 boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
//如果有stack的移动,比如从桌面启动Activity时,那么要将被移动到后台的Launcher所在stack执行pause操作;执行startPausingLocked
//返回true时代表上一个resumed的Activity正在pausing状态
2488 if (mResumedActivity != null) {
2489 if (DEBUG_STATES) Slog.d(TAG_STATES,
2490 "resumeTopActivityLocked: Pausing " + mResumedActivity);
//在第一次startPausingLocked中会将mResumedActivity置空,保证第二次不再调用
2491 pausing |= startPausingLocked(userLeaving, false, next, false);
2492 }
2493 if (pausing && !resumeWhilePausing) {
//pausing = true,正处于pausing状态且等到pause执行完成再resume,那么这里先返回,
//等到下次在completePausedLocked中重新调用resumeFocusedStackTopActivityLocked时这里就不再调用
2494 if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
2495 "resumeTopActivityLocked: Skip resume: need to start pausing");
2496 // At this point we want to put the upcoming activity's process
2497 // at the top of the LRU list, since we know we will be needing it
2498 // very soon and it would be a waste to let it get killed if it
2499 // happens to be sitting towards the end.
2500 if (next.app != null && next.app.thread != null) {
2501 mService.updateLruProcessLocked(next.app, true, null);
2502 }
2503 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2504 if (lastResumed != null) {
2505 lastResumed.setWillCloseOrEnterPip(true);
2506 }
2507 return true;
2508 } else if (mResumedActivity == next && next.isState(RESUMED)
2509 && mStackSupervisor.allResumedActivitiesComplete()) {
2510 // It is possible for the activity to be resumed when we paused back stacks above if the
2511 // next activity doesn't have to wait for pause to complete.
2512 // So, nothing else to-do except:
2513 // Make sure we have executed any pending transitions, since there
2514 // should be nothing left to do at this point.
2515 executeAppTransition(options);
2516 if (DEBUG_STATES) Slog.d(TAG_STATES,
2517 "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
2518 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2519 return true;
2520 }
2521
2522 // If the most recent activity was noHistory but was only stopped rather
2523 // than stopped+finished because the device went to sleep, we need to make
2524 // sure to finish it as we're making a new activity topmost.
2525 if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
2526 !mLastNoHistoryActivity.finishing) {
2527 if (DEBUG_STATES) Slog.d(TAG_STATES,
2528 "no-history finish of " + mLastNoHistoryActivity + " on new resume");
2529 requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
2530 null, "resume-no-history", false);
2531 mLastNoHistoryActivity = null;
2532 }
2533
2534 if (prev != null && prev != next) {
2535 if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
2536 && next != null && !next.nowVisible) {
2537 mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev); //将prev放入mActivitiesWaitingForVisibleActivity队列,等待next visible
2538 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2539 "Resuming top, waiting visible to hide: " + prev);
2540 } else {
2541 // The next activity is already visible, so hide the previous
2542 // activity's windows right now so we can show the new one ASAP.
2543 // We only do this if the previous is finishing, which should mean
2544 // it is on top of the one being resumed so hiding it quickly
2545 // is good. Otherwise, we want to do the normal route of allowing
2546 // the resumed activity to be shown so we can decide if the
2547 // previous should actually be hidden depending on whether the
2548 // new one is found to be full-screen or not.
2549 if (prev.finishing) {
2550 prev.setVisibility(false);
2551 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2552 "Not waiting for visible to hide: " + prev + ", waitingVisible="
2553 + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
2554 + ", nowVisible=" + next.nowVisible);
2555 } else {
2556 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
2557 "Previous already visible but still waiting to hide: " + prev
2558 + ", waitingVisible="
2559 + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
2560 + ", nowVisible=" + next.nowVisible);
2561 }
2562 }
2563 }
2564
2565 // Launching this app's activity, make sure the app is no longer
2566 // considered stopped.
2567 try {
2568 AppGlobals.getPackageManager().setPackageStoppedState(
2569 next.packageName, false, next.userId); /* TODO: Verify if correct userid */
2570 } catch (RemoteException e1) {
2571 } catch (IllegalArgumentException e) {
2572 Slog.w(TAG, "Failed trying to unstop package "
2573 + next.packageName + ": " + e);
2574 }
2575 //动画相关
2576 // We are starting up the next activity, so tell the window manager
2577 // that the previous one will be hidden soon. This way it can know
2578 // to ignore it when computing the desired screen orientation.
2579 boolean anim = true;
2580 if (mPerf == null) {
2581 mPerf = new BoostFramework();
2582 }
2583 if (prev != null) {
2584 if (prev.finishing) {
2585 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2586 "Prepare close transition: prev=" + prev);
2587 if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
2588 anim = false;
2589 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
2590 } else {
2591 mWindowManager.prepareAppTransition(prev.getTask() == next.getTask()
2592 ? TRANSIT_ACTIVITY_CLOSE
2593 : TRANSIT_TASK_CLOSE, false);
2594 if(prev.getTask() != next.getTask() && mPerf != null) {
2595 mPerf.perfHint(BoostFramework.VENDOR_HINT_ANIM_BOOST,
2596 next.packageName, -1, 1);
2597 }
2598 }
2599 prev.setVisibility(false);
2600 } else {
2601 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
2602 "Prepare open transition: prev=" + prev);
2603 if (mStackSupervisor.mNoAnimActivities.contains(next)) {
2604 anim = false;
2605 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
2606 } else {
2607 mWindowManager.prepareAppTransition(prev.getTask() == next.getTask()
2608 ? TRANSIT_ACTIVITY_OPEN
2609 : next.mLaunchTaskBehind
2610 ? TRANSIT_TASK_OPEN_BEHIND
2611 : TRANSIT_TASK_OPEN, false);
2612 if(prev.getTask() != next.getTask() && mPerf != null) {
2613 mPerf.perfHint(BoostFramework.VENDOR_HINT_ANIM_BOOST,
2614 next.packageName, -1, 1);
2615 }
2616 }
2617 }
2618 } else {
2619 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
2620 if (mStackSupervisor.mNoAnimActivities.contains(next)) {
2621 anim = false;
2622 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
2623 } else {
2624 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
2625 }
2626 }
2627
2628 if (anim) {
2629 next.applyOptionsLocked();
2630 } else {
2631 next.clearOptionsLocked();
2632 }
2633
2634 mStackSupervisor.mNoAnimActivities.clear();
2635
2636 ActivityStack lastStack = mStackSupervisor.getLastStack();
2637 if (next.app != null && next.app.thread != null) { //Activity第一次创建时这个条件不满足,因为ActivityRecord的app属性是在startSpecificActivityLocked->realStartActivityLocked中赋值;再次调用到这里一般是复用Activity的情况了
2638 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
2639 + " stopped=" + next.stopped + " visible=" + next.visible);
2640
2641 // If the previous activity is translucent, force a visibility update of
2642 // the next activity, so that it's added to WM's opening app list, and
2643 // transition animation can be set up properly.
2644 // For example, pressing Home button with a translucent activity in focus.
2645 // Launcher is already visible in this case. If we don't add it to opening
2646 // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
2647 // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
2648 final boolean lastActivityTranslucent = lastStack != null
2649 && (lastStack.inMultiWindowMode()
2650 || (lastStack.mLastPausedActivity != null
2651 && !lastStack.mLastPausedActivity.fullscreen));
2652
2653 // The contained logic must be synchronized, since we are both changing the visibility
2654 // and updating the {@link Configuration}. {@link ActivityRecord#setVisibility} will
2655 // ultimately cause the client code to schedule a layout. Since layouts retrieve the
2656 // current {@link Configuration}, we must ensure that the below code updates it before
2657 // the layout can occur.
2658 synchronized(mWindowManager.getWindowManagerLock()) {
2659 // This activity is now becoming visible.
2660 if (!next.visible || next.stopped || lastActivityTranslucent) {
2661 next.setVisibility(true);
2662 }
2663
2664 // schedule launch ticks to collect information about slow apps.
2665 next.startLaunchTickingLocked();
2666
2667 ActivityRecord lastResumedActivity =
2668 lastStack == null ? null :lastStack.mResumedActivity;
2669 final ActivityState lastState = next.getState();
2670
2671 mService.updateCpuStats();
2672
2673 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next
2674 + " (in existing)");
2675
2676 next.setState(RESUMED, "resumeTopActivityInnerLocked"); //设为resumed的状态
2677
2678 mService.updateLruProcessLocked(next.app, true, null);
2679 updateLRUListLocked(next);
2680 mService.updateOomAdjLocked();
2681
2682 // Have the window manager re-evaluate the orientation of
2683 // the screen based on the new activity order.
2684 boolean notUpdated = true;
2685
2686 if (mStackSupervisor.isFocusedStack(this)) {
2687 // We have special rotation behavior when here is some active activity that
2688 // requests specific orientation or Keyguard is locked. Make sure all activity
2689 // visibilities are set correctly as well as the transition is updated if needed
2690 // to get the correct rotation behavior. Otherwise the following call to update
2691 // the orientation may cause incorrect configurations delivered to client as a
2692 // result of invisible window resize.
2693 // TODO: Remove this once visibilities are set correctly immediately when
2694 // starting an activity.
2695 notUpdated = !mStackSupervisor.ensureVisibilityAndConfig(next, mDisplayId,
2696 true /* markFrozenIfConfigChanged */, false /* deferResume */);
2697 }
2698
2699 if (notUpdated) {
2700 // The configuration update wasn't able to keep the existing
2701 // instance of the activity, and instead started a new one.
2702 // We should be all done, but let's just make sure our activity
2703 // is still at the top and schedule another run if something
2704 // weird happened.
2705 ActivityRecord nextNext = topRunningActivityLocked();
2706 if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
2707 "Activity config changed during resume: " + next
2708 + ", new next: " + nextNext);
2709 if (nextNext != next) {
2710 // Do over!
2711 mStackSupervisor.scheduleResumeTopActivities();
2712 }
2713 if (!next.visible || next.stopped) {
2714 next.setVisibility(true);
2715 }
2716 next.completeResumeLocked();
2717 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2718 return true;
2719 }
2720
2721 try {
2722 final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
2723 next.appToken);
2724 // Deliver all pending results.
2725 ArrayList<ResultInfo> a = next.results;
2726 if (a != null) {
2727 final int N = a.size();
2728 if (!next.finishing && N > 0) {
2729 if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
2730 "Delivering results to " + next + ": " + a);
2731 transaction.addCallback(ActivityResultItem.obtain(a));
2732 }
2733 }
2734
2735 if (next.newIntents != null) {
2736 transaction.addCallback(NewIntentItem.obtain(next.newIntents,
2737 false /* andPause */));
2738 }
2739
2740 // Well the app will no longer be stopped.
2741 // Clear app token stopped state in window manager if needed.
2742 next.notifyAppResumed(next.stopped);
2743
2744 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
2745 System.identityHashCode(next), next.getTask().taskId,
2746 next.shortComponentName);
2747
2748 next.sleeping = false;
2749 mService.getAppWarningsLocked().onResumeActivity(next);
2750 mService.showAskCompatModeDialogLocked(next);
2751 next.app.pendingUiClean = true;
2752 next.app.forceProcessStateUpTo(mService.mTopProcessState);
2753 next.clearOptionsLocked();
2754 transaction.setLifecycleStateRequest(
2755 ResumeActivityItem.obtain(next.app.repProcState,
2756 mService.isNextTransitionForward()));
2757 mService.getLifecycleManager().scheduleTransaction(transaction); //直接调用resumed逻辑
2758
2759 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
2760 + next);
2761 } catch (Exception e) {
2762 // Whoops, need to restart this activity!
2763 if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
2764 + lastState + ": " + next);
2765 next.setState(lastState, "resumeTopActivityInnerLocked");
2766
2767 // lastResumedActivity being non-null implies there is a lastStack present.
2768 if (lastResumedActivity != null) {
2769 lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked");
2770 }
2771
2772 Slog.i(TAG, "Restarting because process died: " + next);
2773 if (!next.hasBeenLaunched) {
2774 next.hasBeenLaunched = true;
2775 } else if (SHOW_APP_STARTING_PREVIEW && lastStack != null
2776 && getDisplay() != null && lastStack.isTopStackOnDisplay()) {
2777 next.showStartingWindow(null /* prev */, false /* newTask */,
2778 false /* taskSwitch */);
2779 }
2780 mStackSupervisor.startSpecificActivityLocked(next, true, false);
2781 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2782 return true;
2783 }
2784 }
2785
2786 // From this point on, if something goes wrong there is no way
2787 // to recover the activity.
2788 try {
2789 next.completeResumeLocked();
2790 } catch (Exception e) {
2791 // If any exception gets thrown, toss away this
2792 // activity and try the next one.
2793 Slog.w(TAG, "Exception thrown during resume of " + next, e);
2794 requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
2795 "resume-exception", true);
2796 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2797 return true;
2798 }
2799 } else {
2800 // Whoops, need to restart this activity!
2801 if (!next.hasBeenLaunched) {
2802 next.hasBeenLaunched = true;
2803 } else {
2804 if (SHOW_APP_STARTING_PREVIEW) {
2805 next.showStartingWindow(null /* prev */, false /* newTask */,
2806 false /* taskSwich */);
2807 }
2808 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
2809 }
2810 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
2811 mStackSupervisor.startSpecificActivityLocked(next, true, true); //第一次创建时调用startSpecificActivityLocked
2812 }
2813
2814 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
2815 return true;
2816 }
resumeTopActivityInnerLocked是pause,resume流程的主要逻辑
![](https://img.haomeiwen.com/i6635796/a75a441910cc6cb4.png)