美文网首页
Activity/应用(O/8.0)启动流程(二)旧Activi

Activity/应用(O/8.0)启动流程(二)旧Activi

作者: 小川君 | 来源:发表于2018-11-08 20:44 被阅读0次

    Activity/应用(O/8.0)启动流程(一)
    Activity/应用(O/8.0)启动流程(二)
    Activity/应用(O/8.0)启动流程(三)
    Activity/应用(O/8.0)启动流程(四)

    上一篇主要是为需要被启动的Activity设置栈信息,要么新建,要么复用。
    而遗留的小问题是栈的具体查找赋值,我们现在来具体说一下

    setTaskFromReuseOrCreateNewTask 复用栈或者新建栈
    setTaskFromSourceRecord 使用执行启动Activity所在的栈
    setTaskFromInTask 使用在执行启动时,具体指定的栈
    setTaskToCurrentTopOrCreateNewTask 注释说永远也不会发生,而且我也没有看懂什么意思,这里就不再多说了
    我们主要来看setTaskFromReuseOrCreateNewTask ,因为下面的那种方式都是复用的,并不涉及创建,这里就不再说了

       private int setTaskFromReuseOrCreateNewTask(
                TaskRecord taskToAffiliate, int preferredLaunchStackId, ActivityStack topStack) {
             // 获取或创建一个ActivityStack
            mTargetStack = computeStackFocus(
                    mStartActivity, true, mLaunchBounds, mLaunchFlags, mOptions);
    
            // Do no move the target stack to front yet, as we might bail if
            // isLockTaskModeViolation fails below.
    
            if (mReuseTask == null) {
               // 如果没有可以复用的任务栈TaskRecord 那么就通过ActivityStack创建一个,并保存到ActivityStack中
                final TaskRecord task = mTargetStack.createTaskRecord(
                        mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                        mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                        mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
                        mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity.mActivityType);
                addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
                if (mLaunchBounds != null) {
                    final int stackId = mTargetStack.mStackId;
                    if (StackId.resizeStackWithLaunchBounds(stackId)) {
                        mService.resizeStack(
                                stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1);
                    } else {
                        mStartActivity.getTask().updateOverrideConfiguration(mLaunchBounds);
                    }
                }
                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 (mSupervisor.isLockTaskModeViolation(mStartActivity.getTask())) {
                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
    
            if (!mMovedOtherTask) {
                // If stack id is specified in activity options, usually it means that activity is
                // launched not from currently focused stack (e.g. from SysUI or from shell) - in
                // that case we check the target stack.
                updateTaskReturnToType(mStartActivity.getTask(), mLaunchFlags,
                        preferredLaunchStackId != INVALID_STACK_ID ? mTargetStack : topStack);
            }
            //  将ActivityStack移动到前台 
            if (mDoResume) {
                mTargetStack.moveToFront("reuseOrNewTask");
            }
            return START_SUCCESS;
        }
    

    我们主要来看两个地方,一个是获取ActivityStack一个是创建TaskRecord

     //  获取ActivityStack
        private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, Rect bounds,
                int launchFlags, ActivityOptions aOptions) {
              // 首先获取启动栈ActivityStack,
             //   如果ActivityStack不为空,则直接返回
            final TaskRecord task = r.getTask();
            ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
            if (stack != null) {
                return stack;
            }
           //  如果启动栈里面没有对应的ActivityStack,然后判断将要启动的Activity对应的任务栈所在的ActivityStack,如果不为空则直接返回
            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 (mSourceDisplayId != DEFAULT_DISPLAY) {
                // Try to put the activity in a stack on a secondary display.
                stack = mSupervisor.getValidLaunchStackOnDisplay(mSourceDisplayId, 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 mSourceDisplayId=" + mSourceDisplayId
                                    + ", looking on all displays.");
                    stack = mSupervisor.getNextValidLaunchStackLocked(r, mSourceDisplayId);
                }
            }
           //  如果最终我们还是没有获取到ActivityStack,那么我们就要遍历当前屏幕下的所有ActivityStack
            if (stack == null) {
                // We first try to put the task in the first dynamic stack on home display.
                final ArrayList<ActivityStack> homeDisplayStacks = mSupervisor.mHomeStack.mStacks;
                for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
                    stack = homeDisplayStacks.get(stackNdx);
                   //  如果是动态创建的栈,则直接返回(getLanucher中会说几种ActivityStack的类型,除了普通应用使用的ActivityStack,其他的都是静态栈)
                    if (isDynamicStack(stack.mStackId)) {
                        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.
                final int stackId = task != null ? task.getLaunchStackId() :
                        bounds != null ? FREEFORM_WORKSPACE_STACK_ID :
                                FULLSCREEN_WORKSPACE_STACK_ID;
                //  如果最终我们还是没有拿到,则通过ActivityStackSupervisor动态创建一个ActivityStack,并保存下来
                stack = mSupervisor.getStack(stackId, CREATE_IF_NEEDED, ON_TOP);
            }
            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
                    + r + " stackId=" + stack.mStackId);
            return stack;
        }
    
     private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
                ActivityOptions aOptions) {
            // We are reusing a task, keep the stack!
             //  如果复用的任务栈不为空,则直接返回该任务栈所对应的ActivityStack
            if (mReuseTask != null) {
                return mReuseTask.getStack();
            }
    
            // If the activity is of a specific type, return the associated stack, creating it if
            // necessary
            //  ActivityStack的种类分为四种
            //   APPLICATION_ACTIVITY_TYPE  普通应用类型
            //    HOME_ACTIVITY_TYPE   桌面应用类型
           //     RECENTS_ACTIVITY_TYPE   显示最近任务应用类型(我们按下菜单键的时候,会出现一个最近任务列表,这个就是界面就是RecentsActivity)
          //  ASSISTANT_ACTIVITY_TYPE  这个我就不怎么清楚了 不过找到了一个   
          //  VoiceInteractionManagerService和VoiceInteractionSession脑袋大了不少,这里就暂时不分析了
    
       //  下面的几个判断就是根据要启动的Activity类型 获取相对应的ActivityStack
            if (r.isHomeActivity()) {
                return mSupervisor.mHomeStack;
            }
            if (r.isRecentsActivity()) {
                return mSupervisor.getStack(RECENTS_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
            }
            if (r.isAssistantActivity()) {
                return mSupervisor.getStack(ASSISTANT_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
            }
    
            final int launchDisplayId =
                    (aOptions != null) ? aOptions.getLaunchDisplayId() : INVALID_DISPLAY;
    
            final int launchStackId =
                    (aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID;
    
            if (launchStackId != INVALID_STACK_ID && launchDisplayId != INVALID_DISPLAY) {
                throw new IllegalArgumentException(
                        "Stack and display id can't be set at the same time.");
            }
    
            if (isValidLaunchStackId(launchStackId, launchDisplayId, r)) {
                return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP);
            }
            if (launchStackId == DOCKED_STACK_ID) {
                // The preferred launch stack is the docked stack, but it isn't a valid launch stack
                // for this activity, so we put the activity in the fullscreen stack.
                return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
            }
            if (launchDisplayId != INVALID_DISPLAY) {
                // Stack id has higher priority than display id.
                return mSupervisor.getValidLaunchStackOnDisplay(launchDisplayId, r);
            }
    
            // If we are using Vr2d display, find the virtual display stack.
            if (mUsingVr2dDisplay) {
                ActivityStack as = mSupervisor.getValidLaunchStackOnDisplay(mSourceDisplayId, r);
                if (DEBUG_STACK) {
                    Slog.v(TAG, "Launch stack for app: " + r.toString() +
                        ", on virtual display stack:" + as.toString());
                }
                return as;
            }
    
            if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
                     || mSourceDisplayId != DEFAULT_DISPLAY) {
                return null;
            }
            // Otherwise handle adjacent launch.
    
            // The parent activity doesn't want to launch the activity on top of itself, but
            // instead tries to put it onto other side in side-by-side mode.
            //  这里获取一个ActivityStack对象,要么是任务栈所对应的ActivityStack,要么是当前前台的ActivityStack
            final ActivityStack parentStack = task != null ? task.getStack(): mSupervisor.mFocusedStack;
           //  如果是任务栈所对应的ActivityStack则直接返回
            if (parentStack != mSupervisor.mFocusedStack) {
                // If task's parent stack is not focused - use it during adjacent launch.
                return parentStack;
            } else {
              //  如果位于前台的ActivityStack不为空,并且该ActivityStack的顶部的任务栈等于要启动的Activity所对应的任务栈,则直接返回前台栈
                if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
                    // If task is already on top of focused stack - use it. We don't want to move the
                    // existing focused task to adjacent stack, just deliver new intent in this case.
                    return mSupervisor.mFocusedStack;
                }
    
               //  下面的是分屏的,这里就不再分析(因为我也看不懂啊。)
                if (parentStack != null && parentStack.isDockedStack()) {
                    // If parent was in docked stack, the natural place to launch another activity
                    // will be fullscreen, so it can appear alongside the docked window.
                    return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED,
                            ON_TOP);
                } else {
                    // If the parent is not in the docked stack, we check if there is docked window
                    // and if yes, we will launch into that stack. If not, we just put the new
                    // activity into parent's stack, because we can't find a better place.
                    final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID);
                    if (dockedStack != null
                            && dockedStack.shouldBeVisible(r) == STACK_INVISIBLE) {
                        // There is a docked stack, but it isn't visible, so we can't launch into that.
                        return null;
                    } else {
                        return dockedStack;
                    }
                }
            }
        }
    
    

    上面简单说了ActivityStack创建过程,下面简单说一下TaskRecord的创建过程

    //  ActivityStack#createTaskRecord
        TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                boolean toTop, int type) {
            //  创建TaskRecord ,并加入集合里面
            TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
                    voiceInteractor, type);
            // add the task to stack first, mTaskPositioner might need the stack association
            addTask(task, toTop, "createTaskRecord");
            final boolean isLockscreenShown = mService.mStackSupervisor.mKeyguardController
                    .isKeyguardShowing(mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY);
            if (!layoutTaskInStack(task, info.windowLayout) && mBounds != null && task.isResizeable()
                    && !isLockscreenShown) {
                task.updateOverrideConfiguration(mBounds);
            }
            task.createWindowContainer(toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
            return task;
        }
    

    ok,栈的创建就完结啦,下面也是接着上一篇的说

    1)在栈信息配置完之后,我们会继续进行我们的启动工作,下面要说的就是将我们执行启动的Activity进行暂停操作,
    //  ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
       boolean resumeFocusedStackTopActivityLocked(
                ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    
            if (!readyToResume()) {
                return false;
            }
            
            // 目标栈不为空 , 并且刚刚也把此栈移动到了前台  所以 会进入这个判断体 
            if (targetStack != null && isFocusedStack(targetStack)) {
                return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }
    
            final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
            if (r == null || r.state != RESUMED) {
                mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
            } else if (r.state == RESUMED) {
                // Kick off any lingering app transitions form the MoveTaskToFront operation.
                mFocusedStack.executeAppTransition(targetOptions);
            }
            return false;
        }
    

    ActivityStack#resumeTopActivityUncheckedLocked -> resumeTopActivityInnerLocked
    ActivityStack#resumeTopActivityInnerLocked: 这个类有点绕,因为会调用两次,此时是第一次,只看第一次的标识即可,第二次要进入的时候会再次提醒,没有标识的代表通用:

        private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
             // 首先确认下入参  
             //  第一次 prev为即将要启动的Activity
           //  第二次  prev执行启动的Activity 已暂停的Activity 可以理解为上一个Activity
            if (!mService.mBooting && !mService.mBooted) {
                // Not ready yet!
                return false;
            }
       
            // Find the next top-most activity to resume in this stack that is not finishing and is
            // focusable. If it is not focusable, we will fall into the case below to resume the
            // top activity in the next focusable task.
            //  在此栈中找到可以获取焦点的Activity,也就是我们即将要启动的activity
            final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    
            final boolean hasRunningActivity = next != null;
    
            // TODO: Maybe this entire condition can get removed?
            if (hasRunningActivity && getDisplay() == null) {
                return false;
            }
    
            mStackSupervisor.cancelInitializingActivities();
    
            // Remember how we'll process this pause/resume situation, and ensure
            // that the state is reset however we wind up proceeding.
            final boolean userLeaving = mStackSupervisor.mUserLeaving;
            mStackSupervisor.mUserLeaving = false;
    
            if (!hasRunningActivity) {
                // There are no activities left in the stack, let's look somewhere else.
                return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
            }
    
            next.delayedResume = false;
    
            // If the top activity is the resumed one, nothing to do.
           //  如果没有其他的RESUMED状态的activity,则进入判断体,allResumedActivitiesComplete判断是否还有RESUMED状态的Activity,如果有则返回false
            if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                        mStackSupervisor.allResumedActivitiesComplete()) {
                // Make sure we have executed any pending transitions, since there
                // should be nothing left to do at this point.
                executeAppTransition(options);
                if (DEBUG_STATES) Slog.d(TAG_STATES,
                        "resumeTopActivityLocked: Top activity resumed " + next);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return false;
            }
    
            final TaskRecord nextTask = next.getTask();
            final TaskRecord prevTask = prev != null ? prev.getTask() : null;
            if (prevTask != null && prevTask.getStack() == this &&
                    prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
                if (DEBUG_STACK)  mStackSupervisor.validateTopActivitiesLocked();
                if (prevTask == nextTask) {
                    prevTask.setFrontOfTask();
                } else if (prevTask != topTask()) {
                    // This task is going away but it was supposed to return to the home stack.
                    // Now the task above it has to return to the home task instead.
                    final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
                    mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
                } else if (!isOnHomeDisplay()) {
                    return false;
                } else if (!isHomeStack()){
                    if (DEBUG_STATES) Slog.d(TAG_STATES,
                            "resumeTopActivityLocked: Launching home next");
                    return isOnHomeDisplay() &&
                            mStackSupervisor.resumeHomeStackTask(prev, "prevFinished");
                }
            }
    
            // If we are sleeping, and there is no resumed activity, and the top
            // activity is paused, well that is the state we want.
           //  如果所有的Activity都进入了pause状态  这就是我们想要的状态 就会进入判断体 
          //  allPausedActivitiesComplete判断所有的Activity是否进入了pause/STOP/STOPPING  ,也就是判断是否还有RESUME状态的Activity,
           //上一个执行启动操作的activity还是resume状态的,虽然将要启动的activity所对应的栈已经被移动到了前台,所以这里也不会进入判断体
            if (shouldSleepOrShutDownActivities()
                    && mLastPausedActivity == next
                    && mStackSupervisor.allPausedActivitiesComplete()) {
                // Make sure we have executed any pending transitions, since there
                // should be nothing left to do at this point.
                executeAppTransition(options);
                if (DEBUG_STATES) Slog.d(TAG_STATES,
                        "resumeTopActivityLocked: Going to sleep and all paused");
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return false;
            }
    
            // Make sure that the user who owns this activity is started.  If not,
            // we will just leave it as is because someone should be bringing
            // another user's activities to the top of the stack.
            if (!mService.mUserController.hasStartedUserState(next.userId)) {
                Slog.w(TAG, "Skipping resume of top activity " + next
                        + ": user " + next.userId + " is stopped");
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return false;
            }
    
            // The activity may be waiting for stop, but that is no longer
            // appropriate for it.
            mStackSupervisor.mStoppingActivities.remove(next);
            mStackSupervisor.mGoingToSleepActivities.remove(next);
            next.sleeping = false;
            mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
    
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
    
            // If we are currently pausing an activity, then don't do anything until that is done.
            if (!mStackSupervisor.allPausedActivitiesComplete()) {
                if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                        "resumeTopActivityLocked: Skip resume: some activity pausing.");
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return false;
            }
    
            mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
    
            boolean lastResumedCanPip = false;
            final ActivityStack lastFocusedStack = mStackSupervisor.getLastStack();
            if (lastFocusedStack != null && lastFocusedStack != this) {
                // So, why aren't we using prev here??? See the param comment on the method. prev doesn't
                // represent the last resumed activity. However, the last focus stack does if it isn't null.
                final ActivityRecord lastResumed = lastFocusedStack.mResumedActivity;
                lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
                        "resumeTopActivity", userLeaving /* beforeStopping */);
            }
            // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity
            // to be paused, while at the same time resuming the new resume activity only if the
            // previous activity can't go into Pip since we want to give Pip activities a chance to
            // enter Pip before resuming the next activity.
            //  这个标识我不太懂,但是因为目前还有RESUMED状态的Activity,所以可以暂时理解为lastResumedCanPip == true,resumeWhilePausing == false,最后再下面的判断整体返回
            final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
                    && !lastResumedCanPip;
             //  第一次     此处判断是否有需要执行pause状态的Activity,上面我们说了  执行启动的Activity目前还是RESUME状态,所以这里会返回true
           //  第二次    next代表我们将要启动的Activity,不需要进行暂停操作,返回false
            boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
            if (mResumedActivity != null) {
                if (DEBUG_STATES) Slog.d(TAG_STATES,
                        "resumeTopActivityLocked: Pausing " + mResumedActivity);
                pausing |= startPausingLocked(userLeaving, false, next, false);
            }
           //  ok 第一次执行到这里就结束了     下面继续要走的都是第二次  不在区分
            if (pausing && !resumeWhilePausing) {
                if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
                        "resumeTopActivityLocked: Skip resume: need to start pausing");
                // At this point we want to put the upcoming activity's process
                // at the top of the LRU list, since we know we will be needing it
                // very soon and it would be a waste to let it get killed if it
                // happens to be sitting towards the end.
                if (next.app != null && next.app.thread != null) {
                    mService.updateLruProcessLocked(next.app, true, null);
                }
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                    mStackSupervisor.allResumedActivitiesComplete()) {
                // It is possible for the activity to be resumed when we paused back stacks above if the
                // next activity doesn't have to wait for pause to complete.
                // So, nothing else to-do except:
                // Make sure we have executed any pending transitions, since there
                // should be nothing left to do at this point.
                executeAppTransition(options);
                if (DEBUG_STATES) Slog.d(TAG_STATES,
                        "resumeTopActivityLocked: Top activity resumed (dontWaitForPause) " + next);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
    
            // If the most recent activity was noHistory but was only stopped rather
            // than stopped+finished because the device went to sleep, we need to make
            // sure to finish it as we're making a new activity topmost.
            if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
                    !mLastNoHistoryActivity.finishing) {
                if (DEBUG_STATES) Slog.d(TAG_STATES,
                        "no-history finish of " + mLastNoHistoryActivity + " on new resume");
                requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                        null, "resume-no-history", false);
                mLastNoHistoryActivity = null;
            }
    
            if (prev != null && prev != next) {
                if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
                        && next != null && !next.nowVisible) {
                    mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev);
                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                            "Resuming top, waiting visible to hide: " + prev);
                } else {
                    // The next activity is already visible, so hide the previous
                    // activity's windows right now so we can show the new one ASAP.
                    // We only do this if the previous is finishing, which should mean
                    // it is on top of the one being resumed so hiding it quickly
                    // is good.  Otherwise, we want to do the normal route of allowing
                    // the resumed activity to be shown so we can decide if the
                    // previous should actually be hidden depending on whether the
                    // new one is found to be full-screen or not.
                    if (prev.finishing) {
                        prev.setVisibility(false);
                        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                                "Not waiting for visible to hide: " + prev + ", waitingVisible="
                                + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
                                + ", nowVisible=" + next.nowVisible);
                    } else {
                        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                                "Previous already visible but still waiting to hide: " + prev
                                + ", waitingVisible="
                                + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
                                + ", nowVisible=" + next.nowVisible);
                    }
                }
            }
    
            // Launching this app's activity, make sure the app is no longer
            // considered stopped.
            try {
                AppGlobals.getPackageManager().setPackageStoppedState(
                        next.packageName, false, next.userId); /* TODO: Verify if correct userid */
            } catch (RemoteException e1) {
            } catch (IllegalArgumentException e) {
                Slog.w(TAG, "Failed trying to unstop package "
                        + next.packageName + ": " + e);
            }
    
            // We are starting up the next activity, so tell the window manager
            // that the previous one will be hidden soon.  This way it can know
            // to ignore it when computing the desired screen orientation.
            boolean anim = true;
            if (prev != null) {
                if (prev.finishing) {
                    if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                            "Prepare close transition: prev=" + prev);
                    if (mNoAnimActivities.contains(prev)) {
                        anim = false;
                        mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
                    } else {
                        mWindowManager.prepareAppTransition(prev.getTask() == next.getTask()
                                ? TRANSIT_ACTIVITY_CLOSE
                                : TRANSIT_TASK_CLOSE, false);
                    }
                    prev.setVisibility(false);
                } else {
                    if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                            "Prepare open transition: prev=" + prev);
                    if (mNoAnimActivities.contains(next)) {
                        anim = false;
                        mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
                    } else {
                        mWindowManager.prepareAppTransition(prev.getTask() == next.getTask()
                                ? TRANSIT_ACTIVITY_OPEN
                                : next.mLaunchTaskBehind
                                        ? TRANSIT_TASK_OPEN_BEHIND
                                        : TRANSIT_TASK_OPEN, false);
                    }
                }
            } else {
                if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: no previous");
                if (mNoAnimActivities.contains(next)) {
                    anim = false;
                    mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
                } else {
                    mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false);
                }
            }
    
            Bundle resumeAnimOptions = null;
            if (anim) {
                ActivityOptions opts = next.getOptionsForTargetActivityLocked();
                if (opts != null) {
                    resumeAnimOptions = opts.toBundle();
                }
                next.applyOptionsLocked();
            } else {
                next.clearOptionsLocked();
            }
             // 获取当前有焦点的栈,也就是我们将要启动的Activity所在的栈
            ActivityStack lastStack = mStackSupervisor.getLastStack();
             //  next代表我们将要启动的Activity,但是还没有分配进程以及线程 所以下面的不会进入(如果复用了Activity除外)
            if (next.app != null && next.app.thread != null) {
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
                        + " stopped=" + next.stopped + " visible=" + next.visible);
    
                // If the previous activity is translucent, force a visibility update of
                // the next activity, so that it's added to WM's opening app list, and
                // transition animation can be set up properly.
                // For example, pressing Home button with a translucent activity in focus.
                // Launcher is already visible in this case. If we don't add it to opening
                // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
                // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
                final boolean lastActivityTranslucent = lastStack != null
                        && (!lastStack.mFullscreen
                        || (lastStack.mLastPausedActivity != null
                        && !lastStack.mLastPausedActivity.fullscreen));
    
                // The contained logic must be synchronized, since we are both changing the visibility
                // and updating the {@link Configuration}. {@link ActivityRecord#setVisibility} will
                // ultimately cause the client code to schedule a layout. Since layouts retrieve the
                // current {@link Configuration}, we must ensure that the below code updates it before
                // the layout can occur.
                synchronized(mWindowManager.getWindowManagerLock()) {
                    // This activity is now becoming visible.
                    if (!next.visible || next.stopped || lastActivityTranslucent) {
                        next.setVisibility(true);
                    }
    
                    // schedule launch ticks to collect information about slow apps.
                    next.startLaunchTickingLocked();
    
                    ActivityRecord lastResumedActivity =
                            lastStack == null ? null :lastStack.mResumedActivity;
                    ActivityState lastState = next.state;
    
                    mService.updateCpuStats();
    
                    if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next
                            + " (in existing)");
    
                    setResumedActivityLocked(next, "resumeTopActivityInnerLocked");
    
                    mService.updateLruProcessLocked(next.app, true, null);
                    updateLRUListLocked(next);
                    mService.updateOomAdjLocked();
    
                    // Have the window manager re-evaluate the orientation of
                    // the screen based on the new activity order.
                    boolean notUpdated = true;
    
                    if (mStackSupervisor.isFocusedStack(this)) {
    
                        // We have special rotation behavior when Keyguard is locked. Make sure all
                        // activity visibilities are set correctly as well as the transition is updated
                        // if needed to get the correct rotation behavior.
                        // TODO: Remove this once visibilities are set correctly immediately when
                        // starting an activity.
                        if (mStackSupervisor.mKeyguardController.isKeyguardLocked()) {
                            mStackSupervisor.ensureActivitiesVisibleLocked(null /* starting */,
                                    0 /* configChanges */, false /* preserveWindows */);
                        }
                        final Configuration config = mWindowManager.updateOrientationFromAppTokens(
                                mStackSupervisor.getDisplayOverrideConfiguration(mDisplayId),
                                next.mayFreezeScreenLocked(next.app) ? next.appToken : null,
                                        mDisplayId);
                        if (config != null) {
                            next.frozenBeforeDestroy = true;
                        }
                        notUpdated = !mService.updateDisplayOverrideConfigurationLocked(config, next,
                                false /* deferResume */, mDisplayId);
                    }
    
                    if (notUpdated) {
                        // The configuration update wasn't able to keep the existing
                        // instance of the activity, and instead started a new one.
                        // We should be all done, but let's just make sure our activity
                        // is still at the top and schedule another run if something
                        // weird happened.
                        ActivityRecord nextNext = topRunningActivityLocked();
                        if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
                                "Activity config changed during resume: " + next
                                        + ", new next: " + nextNext);
                        if (nextNext != next) {
                            // Do over!
                            mStackSupervisor.scheduleResumeTopActivities();
                        }
                        if (!next.visible || next.stopped) {
                            next.setVisibility(true);
                        }
                        next.completeResumeLocked();
                        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                        return true;
                    }
    
                    try {
                        // Deliver all pending results.
                        ArrayList<ResultInfo> a = next.results;
                        if (a != null) {
                            final int N = a.size();
                            if (!next.finishing && N > 0) {
                                if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                                        "Delivering results to " + next + ": " + a);
                                next.app.thread.scheduleSendResult(next.appToken, a);
                            }
                        }
    
                        if (next.newIntents != null) {
                            next.app.thread.scheduleNewIntent(
                                    next.newIntents, next.appToken, false /* andPause */);
                        }
    
                        // Well the app will no longer be stopped.
                        // Clear app token stopped state in window manager if needed.
                        next.notifyAppResumed(next.stopped);
    
                        EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
                                System.identityHashCode(next), next.getTask().taskId,
                                next.shortComponentName);
    
                        next.sleeping = false;
                        mService.showUnsupportedZoomDialogIfNeededLocked(next);
                        mService.showAskCompatModeDialogLocked(next);
                        next.app.pendingUiClean = true;
                        next.app.forceProcessStateUpTo(mService.mTopProcessState);
                        next.clearOptionsLocked();
                        next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                                mService.isNextTransitionForward(), resumeAnimOptions);
    
                        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
                                + next);
                    } catch (Exception e) {
                        // Whoops, need to restart this activity!
                        if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
                                + lastState + ": " + next);
                        next.state = lastState;
                        if (lastStack != null) {
                            lastStack.mResumedActivity = lastResumedActivity;
                        }
                        Slog.i(TAG, "Restarting because process died: " + next);
                        if (!next.hasBeenLaunched) {
                            next.hasBeenLaunched = true;
                        } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
                                mStackSupervisor.isFrontStackOnDisplay(lastStack)) {
                            next.showStartingWindow(null /* prev */, false /* newTask */,
                                    false /* taskSwitch */);
                        }
                        mStackSupervisor.startSpecificActivityLocked(next, true, false);
                        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                        return true;
                    }
                }
    
                // From this point on, if something goes wrong there is no way
                // to recover the activity.
                try {
                    next.completeResumeLocked();
                } catch (Exception e) {
                    // If any exception gets thrown, toss away this
                    // activity and try the next one.
                    Slog.w(TAG, "Exception thrown during resume of " + next, e);
                    requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
                            "resume-exception", true);
                    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                    return true;
                }
            } else {
                // Whoops, need to restart this activity!
              //  上面的if有点长,上面说了因为没有分配进程与线程  所以下面就是分配进程与线程的操作
                if (!next.hasBeenLaunched) {
                    next.hasBeenLaunched = true;
                } else {
                    if (SHOW_APP_STARTING_PREVIEW) {
                        next.showStartingWindow(null /* prev */, false /* newTask */,
                                false /* taskSwich */);
                    }
                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
                }
                if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
               //  主要是这里   入参为我们将要启动的Activity  以及两个true标识
                mStackSupervisor.startSpecificActivityLocked(next, true, true);
            }
    
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return true;
        }
    
    

    上面的代码看了极度不适,我们先来看pauseBackStacks这个方法;总的来说,就是把执行启动的Activity的状态设置为暂停状态,第一次进入上面的方法,在判断还有RESUMED状态的Activity的时候,会执行pauseBackStacks这个方法将RESUMED状态的Activity设置为PAUSE状态

        //  ActivityStackSupervisor#pauseBackStacks
        boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
            boolean someActivityPaused = false;
            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
                ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                    final ActivityStack stack = stacks.get(stackNdx);
                    if (!isFocusedStack(stack) && stack.mResumedActivity != null) {
                        if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
                                " mResumedActivity=" + stack.mResumedActivity);
                        someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
                                dontWait);
                    }
                }
            }
            return someActivityPaused;
        }
    

    这个方法是遍历所有的栈,找到RESUME状态的Activity,然后执行startPausingLocked

    userLeaving true 在ActivityStarter#startActivityUnchecked -> setInitialState中进行初始化的
    resuming 当前将要启动的Activity
    dontWait false

        //   ActivityStack#startPausingLocked
        final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
                ActivityRecord resuming, boolean pauseImmediately) {
            if (mPausingActivity != null) {
                Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
                        + " state=" + mPausingActivity.state);
                if (!shouldSleepActivities()) {
                    // Avoid recursion among check for sleep and complete pause during sleeping.
                    // Because activity will be paused immediately after resume, just let pause
                    // be completed by the order of activity paused from clients.
                    completePauseLocked(false, resuming);
                }
            }
            //  当前处于RESUMED状态的Activity,也就是执行启动Activity操作的Activity
            ActivityRecord prev = mResumedActivity;
             //   如果没有RESUMED状态的Activity直接返回
            if (prev == null) {
                if (resuming == null) {
                    Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                    // 如果既没有RESUMED状态的Activity并且被启动的Activity也为null的话,调用resumeFocusedStackTopActivityLocked,
                   //  也就是上面我们看了为超级恶心的那个方法,我们也是从那个方法进行了判断才来到这里来进行暂停操作的
                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
                }
                return false;
            }
    
            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
            else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
            mResumedActivity = null;
            mPausingActivity = prev;
            mLastPausedActivity = prev;
            mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                    || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
            prev.state = ActivityState.PAUSING;
            prev.getTask().touchActiveTime();
            clearLaunchTime(prev);
            final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
            if (mService.mHasRecents
                    && (next == null || next.noDisplay || next.getTask() != prev.getTask()
                    || uiSleeping)) {
                prev.mUpdateTaskThumbnailWhenHidden = true;
            }
            stopFullyDrawnTraceIfNeeded();
    
            mService.updateCpuStats();
    
            if (prev.app != null && prev.app.thread != null) {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
                try {
                    EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                            prev.userId, System.identityHashCode(prev),
                            prev.shortComponentName);
                    mService.updateUsageStats(prev, false);
                  //  主要是是在这里执行暂停操作   
                    prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                            userLeaving, prev.configChangeFlags, pauseImmediately);
                } catch (Exception e) {
                    // Ignore exception, if process died other code will cleanup.
                    Slog.w(TAG, "Exception thrown during pause", e);
                    mPausingActivity = null;
                    mLastPausedActivity = null;
                    mLastNoHistoryActivity = null;
                }
            } else {
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
    
            // If we are not going to sleep, we want to ensure the device is
            // awake until the next activity is started.
            if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
                mStackSupervisor.acquireLaunchWakelock();
            }
            //  mPausingActivity 就是我们要暂停的Activity  
            if (mPausingActivity != null) {
                // Have the window manager pause its key dispatching until the new
                // activity has started.  If we're pausing the activity just because
                // the screen is being turned off and the UI is sleeping, don't interrupt
                // key dispatch; the same activity will pick it up again on wakeup.
                if (!uiSleeping) {
                    prev.pauseKeyDispatchingLocked();
                } else if (DEBUG_PAUSE) {
                     Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
                }
                 //pauseImmediately 就是上面我们说的dowait  如果 为true 就是不等待   回进入判断体
                if (pauseImmediately) {
                    // If the caller said they don't want to wait for the pause, then complete
                    // the pause now.
                    completePauseLocked(false, resuming);
                    return false;
    
                } else {
                  //  这里会发送一个暂停的延时消息   最后也是会调用completePauseLocked的
                  // 主要是在Activity暂停之后,通知AMS进行下一步的操作
                    schedulePauseTimeout(prev);
                    return true;
                }
    
            } else {
                // This activity failed to schedule the
                // pause, so just treat it as being paused now.
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
                if (resuming == null) {
                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
                }
                return false;
            }
        }
    

    这里我们会通过ActivityThread去调用我们上一个Activity的onPause方法,并把状态设置为暂停状态
    ActivityThread#schedulePauseActivity -> 发送一个PAUSE_ACTIVITY消息 -> handlePauseActivity()-> performPauseActivity&AMS#activityPaused();
    我们先来看ActivityThread#performPauseActivity的流程:

    ActivityThread#performPauseActivity
        final Bundle performPauseActivity(IBinder token, boolean finished,
                boolean saveState, String reason) {
    //    当我们创建了一个新的Activity时,就会创建一个与之对应的ActivityClientRecord  并保存在mActivities中,具体的时间就是在调用Acitivty之后,
    //      可参考ActivityThread#performLaunchActivity()
            ActivityClientRecord r = mActivities.get(token);
            
            return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
        }
    
    //   ActivityThread#performPauseActivity
      final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
                boolean saveState, String reason) {
            if (r.paused) {
                if (r.activity.mFinished) {
                    // If we are finishing, we won't call onResume() in certain cases.
                    // So here we likewise don't want to call onPause() if the activity
                    // isn't resumed.
                    return null;
                }
                RuntimeException e = new RuntimeException(
                        "Performing pause of activity that is not resumed: "
                        + r.intent.getComponent().toShortString());
                Slog.e(TAG, e.getMessage(), e);
            }
            if (finished) {
                r.activity.mFinished = true;
            }
    
            // Next have the activity save its current state and managed dialogs...
            if (!r.activity.mFinished && saveState) {
                callCallActivityOnSaveInstanceState(r);
            }
            //   直接看这里 
            performPauseActivityIfNeeded(r, reason);
    
            // Notify any outstanding on paused listeners
            ArrayList<OnActivityPausedListener> listeners;
            synchronized (mOnPauseListeners) {
                listeners = mOnPauseListeners.remove(r.activity);
            }
            int size = (listeners != null ? listeners.size() : 0);
            for (int i = 0; i < size; i++) {
                listeners.get(i).onPaused(r.activity);
            }
    
            return !r.activity.mFinished && saveState ? r.state : null;
        }
    
    //    ActivityThread#performPauseActivityIfNeeded
        private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
            if (r.paused) {
                // You are already paused silly...
               //  如果该Acitivty已经处于暂停了 那就直接返回
                return;
            }
    
            try {
                r.activity.mCalled = false;
               //  这里会调用Activity的onPause方法
                mInstrumentation.callActivityOnPause(r.activity);
                EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
                        r.activity.getComponentName().getClassName(), reason);
                if (!r.activity.mCalled) {
                    throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                            + " did not call through to super.onPause()");
                }
            } catch (SuperNotCalledException e) {
                throw e;
            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException("Unable to pause activity "
                            + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
                }
            }
           //  设置对应的ActivityClientRecord的状态为暂停状态 
            r.paused = true;
        }
        //  Instrumentation#callActivityOnPause()
        public void callActivityOnPause(Activity activity) {
           //  到这里  执行启动的Activity算是进入了暂停状态 
            activity.performPause();
        }
    
    2)新进程的分配

    上面就是Activity暂停的状态流程,我们继续来看下一个流程,我们在ActivityStack#startPausingLocked执行了上面的暂停操作之后,之后会通过AMS去启动新的Activity

        //  AMS#activityPaused
       @Override
        public final void activityPaused(IBinder token) {
            final long origId = Binder.clearCallingIdentity();
            synchronized(this) {
                //  先找到该Activity对应的栈
                ActivityStack stack = ActivityRecord.getStackLocked(token);
                if (stack != null) {
                   //  通过栈将该Activity的状态修改为暂停状态,(与其说该Acitivty,不如说是ActivityRecord,到这里我们发现,
                   //   我们先是将ActivityClientRecord设置为暂停状态,然后再将ActivityRecord设置为暂停状态,因为这两个都代表着一个Activity,
                   //   所以需要同时设置为暂停状态)
                    stack.activityPausedLocked(token, false);
                }
            }
            Binder.restoreCallingIdentity(origId);
        }
    
    ActivityStack#activityPausedLocked
      final void activityPausedLocked(IBinder token, boolean timeout) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                "Activity paused: token=" + token + ", timeout=" + timeout);
    
            final ActivityRecord r = isInStackLocked(token);
            if (r != null) {
                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
                if (mPausingActivity == r) {
                    if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                            + (timeout ? " (due to timeout)" : " (pause complete)"));
                    mService.mWindowManager.deferSurfaceLayout();
                    try {
                        // 主要看这里   入参为true和null
                        completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
                    } finally {
                        mService.mWindowManager.continueSurfaceLayout();
                    }
                    return;
                } else {
                    EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                            r.userId, System.identityHashCode(r), r.shortComponentName,
                            mPausingActivity != null
                                ? mPausingActivity.shortComponentName : "(none)");
                    if (r.state == ActivityState.PAUSING) {
                        r.state = ActivityState.PAUSED;
                        if (r.finishing) {
                            if (DEBUG_PAUSE) Slog.v(TAG,
                                    "Executing finish of failed to pause activity: " + r);
                            finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
                        }
                    }
                }
            }
            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
    

    ActivityStack#completePauseLocked

    
        private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
              // 首先获取暂停的Activity,也就是我们执行启动的Activity
            ActivityRecord prev = mPausingActivity;
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
    
            if (prev != null) {
                final boolean wasStopping = prev.state == STOPPING;
                // 设置状态为暂停状态
                prev.state = ActivityState.PAUSED;
                if (prev.finishing) {
                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
                    prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
                } else if (prev.app != null) {
                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
                            + " wasStopping=" + wasStopping + " visible=" + prev.visible);
                      //  会进入到这里  但是这里我不知道什么意思
                    if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) {
                        if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                                "Complete pause, no longer waiting: " + prev);
                    }
                    if (prev.deferRelaunchUntilPaused) {
                        // Complete the deferred relaunch that was waiting for pause to complete.
                        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
                        prev.relaunchActivityLocked(false /* andResume */,
                                prev.preserveWindowOnDeferredRelaunch);
                    } else if (wasStopping) {
                        // We are also stopping, the stop request must have gone soon after the pause.
                        // We can't clobber it, because the stop confirmation will not be handled.
                        // We don't need to schedule another stop, we only need to let it happen.
                        prev.state = STOPPING;
                    } else if (!prev.visible || shouldSleepOrShutDownActivities()) {
                        // Clear out any deferred client hide we might currently have.
                        prev.setDeferHidingClient(false);
                        // If we were visible then resumeTopActivities will release resources before
                        // stopping.
                        addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */);
                    }
                } else {
                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
                    prev = null;
                }
                // It is possible the activity was freezing the screen before it was paused.
                // In that case go ahead and remove the freeze this activity has on the screen
                // since it is no longer visible.
                if (prev != null) {
                    prev.stopFreezingScreenLocked(true /*force*/);
                }
                  // 将被暂停的Activity设置为null
                mPausingActivity = null;
            }
            // 入参为true 上面说过的
            if (resumeNext) {
                //  获取当前有焦点的栈,也就是我们需要被启动的Activity所在栈   
                final ActivityStack topStack = mStackSupervisor.getFocusedStack();
               
                if (!topStack.shouldSleepOrShutDownActivities()) {
                 //  如果当前不是锁屏/关机状态  则会进入这个方法   这个方法在上面说过了,不过两次不一样,代码就不在贴了,
               // 方法有点长,上面也已经加了标识 最终会调用ActivityStackSupervisor#startSpecificActivityLocked创建进程
                    mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
                } else {
                    checkReadyForSleep();
                    ActivityRecord top = topStack.topRunningActivityLocked();
                    if (top == null || (prev != null && top != prev)) {
                        // If there are no more activities available to run, do resume anyway to start
                        // something. Also if the top activity on the stack is not the just paused
                        // activity, we need to go ahead and resume it to ensure we complete an
                        // in-flight app switch.
                        mStackSupervisor.resumeFocusedStackTopActivityLocked();
                    }
                }
            }
    
            if (prev != null) {
                prev.resumeKeyDispatchingLocked();
    
                if (prev.app != null && prev.cpuTimeAtResume > 0
                        && mService.mBatteryStatsService.isOnBattery()) {
                    long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
                            - prev.cpuTimeAtResume;
                    if (diff > 0) {
                        BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
                        synchronized (bsi) {
                            BatteryStatsImpl.Uid.Proc ps =
                                    bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
                                            prev.info.packageName);
                            if (ps != null) {
                                ps.addForegroundTimeLocked(diff);
                            }
                        }
                    }
                }
                prev.cpuTimeAtResume = 0; // reset it
            }
    
            // Notify when the task stack has changed, but only if visibilities changed (not just
            // focus). Also if there is an active pinned stack - we always want to notify it about
            // task stack changes, because its positioning may depend on it.
            if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause
                    || mService.mStackSupervisor.getStack(PINNED_STACK_ID) != null) {
                mService.mTaskChangeNotificationController.notifyTaskStackChanged();
                mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
            }
    
            mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
        }
    

    ActivityStackSupervisor#startSpecificActivityLocked:

        void startSpecificActivityLocked(ActivityRecord r,
                boolean andResume, boolean checkConfig) {
            // Is this activity's application already running?
                 // 先通过AMS根据进程名与uid判断是否存在相应的进程
            ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                    r.info.applicationInfo.uid, true);
    
            r.getStack().setLaunchTime(r);
    
            if (app != null && app.thread != null) {
                try {
                    if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                            || !"android".equals(r.info.packageName)) {
                        // Don't add this if it is a platform component that is marked
                        // to run in multiple processes, because this is actually
                        // part of the framework so doesn't make sense to track as a
                        // separate apk in the process.
                        app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                                mService.mProcessStats);
                    }
                   //  如果存在 则将进程对象传个realStartActivityLocked  直接去启动  这里先留下,我们走不存在的情况
                    realStartActivityLocked(r, app, andResume, checkConfig);
                    return;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting activity "
                            + r.intent.getComponent().flattenToShortString(), e);
                }
    
                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
            //  如果不存在  就需要去创建进程了  
            mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                    "activity", r.intent.getComponent(), false, false, true);
        }
    

    相关文章

      网友评论

          本文标题:Activity/应用(O/8.0)启动流程(二)旧Activi

          本文链接:https://www.haomeiwen.com/subject/xtlgxqtx.html