android之AMS学习攻克

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流程的主要逻辑

startActivity.png
上一篇 下一篇

猜你喜欢

热点阅读