AMS的Activity管理情景1在现有task上启动到同一个task上

分析了栈的管家和栈.有些摸不到头脑,我们顺着一个情景来分析.本文重点关注启动过程actvity的生命周期和调用对于task和stack的管理.
对于怎么去选择task和stack我们在分析activity启动的文章中已经分析了,这里直接从对生命周期处理来分析
首先这种情况选择task是在setTaskFromSourceRecord函数中

private int setTaskFromSourceRecord() {
        final TaskRecord sourceTask = mSourceRecord.task;
        ......
        if (mTargetStack == null) {
            mTargetStack = sourceTask.stack;
        } 
        .....
        if (mDoResume) {
            //1 移动stack到前面
            mTargetStack.moveToFront("sourceStackToFront");
        }
        final TaskRecord topTask = mTargetStack.topTask();
        if (topTask != sourceTask && !mAvoidMoveToFront) {
            //2 移动task到stack前面
                     mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
                    mStartActivity.appTimeTracker, "sourceTaskToFront");
        }
         ......
        // 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.
        //3 设置activity的task
        mStartActivity.setTask(sourceTask, null);
        if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
                + " in existing task " + mStartActivity.task + " from source " + mSourceRecord);
        return START_SUCCESS;
    }

1首先调用ActivityStack的moveToFront函数把stack移动到上边来

void moveToFront(String reason, TaskRecord task) {
        if (!isAttached()) {
            return;
        }

        mStacks.remove(this);
        int addIndex = mStacks.size();

        if (addIndex > 0) {
            final ActivityStack topStack = mStacks.get(addIndex - 1);
            if (StackId.isAlwaysOnTop(topStack.mStackId) && topStack != this) {
                // If the top stack is always on top, we move this stack just below it.
                addIndex--;
            }
        }

        mStacks.add(addIndex, this);

        // TODO(multi-display): Needs to also work if focus is moving to the non-home display.
        if (isOnHomeDisplay()) {
            mStackSupervisor.setFocusStackUnchecked(reason, this);
        }
        if (task != null) {
            insertTaskAtTop(task, null);
        } else {
            task = topTask();
        }
        if (task != null) {
            mWindowManager.moveTaskToTop(task.taskId);
        }
    }

函数首先计算出stack的位置,然后放到对应的位置,如果是在home display上则还要设置这个stack为焦点stack,之后把task插入到stack顶部,最后移动WMS中的task,者几个步骤在此情景都没有任何实质性的变化.
这里可以总结下过程
1 移动stack到前台,moveToFront函数
2 移动task到stack前边,对于window的移动 mWindowManager.moveTaskToTop(task.taskId) 
3 移动activity到task上,请看startActivityLocked函数

mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
  final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
            ActivityOptions options) {
      ......
        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;
                }
                 //2 如果这个task不可见,被全屏的task遮挡,直接插入到task中
                if (task == r.task) {
                    if (!startIt) {
                        task.addActivityToTop(r);
                        r.putInHistory();
                        addConfigOverride(r, task);
                        if (VALIDATE_TOKENS) {
                            validateAppTokensLocked();
                        }
                        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
        //3 task不在前台不需要执行Activity的onUserLeaving函数 设置mUserLeaving为false
        if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
            mStackSupervisor.mUserLeaving = false;
            if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
                    "startActivity() behind front, mUserLeaving=false");
        }

        task = r.task;

        // 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());
        //3 添加activity到task中
        task.addActivityToTop(r);
        //4 更新task中activity的frontOfTask变量,为true代表该activity在task最前面
        task.setFrontOfTask();

        r.putInHistory();
         //5 如果stack不是home stack中,或者activity数量大于0,这种情况要启动starting window
         //因为home stack下面是wall paper不需要启动starting window,而activity为0表示没有要启动的activity
        if (!isHomeStack() || 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.
            //6 进程没有启动或者新的task要显示starting icon
            boolean showStartingIcon = newTask;
            ProcessRecord proc = r.app;
            if (proc == null) {
                proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
            }
            if (proc == null || proc.thread == null) {
                showStartingIcon = true;
            }
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                    "Prepare open transition: starting " + r);
            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
                //7 不需要执行动画设置动画为NONE
                mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
                mNoAnimActivities.add(r);
            } else {
                mWindowManager.prepareAppTransition(newTask
                        ? r.mLaunchTaskBehind
                                ? TRANSIT_TASK_OPEN_BEHIND
                                : TRANSIT_TASK_OPEN
                        : TRANSIT_ACTIVITY_OPEN, keepCurTransition);
                mNoAnimActivities.remove(r);
            }
            //8 添加AppToken到WMS中
            addConfigOverride(r, task);
            boolean doShow = true;
            if (newTask) {
                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;
            }
            if (r.mLaunchTaskBehind) {
                //9 通知wms,activity可见的.虽然是在后台启动
                mWindowManager.setAppVisibility(r.appToken, true);
                ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
                //10 创建starting window
                ActivityRecord prev = r.task.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.task != r.task) {
                        prev = null;
                    }
                    // (2) The current activity is already displayed.
                    else if (prev.nowVisible) {
                        prev = null;
                    }
                }
                //11 如果前面的activity不可见,但是有一个starting window,复用或者新创建一个starting window
                r.showStartingWindow(prev, showStartingIcon);
            }
        } else {
            // If this is the first activity, don't do any fancy animations,
            // because there is nothing for it to animate on top of.
            //12 创建AppWindowToken
            addConfigOverride(r, task);
            ActivityOptions.abort(options);
            options = null;
        }
        if (VALIDATE_TOKENS) {
            validateAppTokensLocked();
        }
    }

我们再在总结下这一步
1 添加activity到task,task.addActivityToTop(r);
2 创建动画
3 创建AppWindowToken到WMS,addConfigOverride(r, task);
4 创建starting window,r.showStartingWindow(prev, showStartingIcon)

下面一个步骤是调用 AMS的方法setFocusedActivityLocked(ActivityRecord r, String reason)

  if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
            mWindowManager.setFocusedApp(r.appToken, true);
        }

主要是更新AMS的mFocusedActivity和更新WMS的mWindowManager.setFocusedApp(r.appToken, true)

设置完成焦点Activity后就执行
resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions); 去真正的activity.

    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        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);
        }
        return false;
    }

前面我们已经把stack移动到前台,设置为focuse activity,所以这里就直接使用resumeTopActivityUncheckedLocked去resume activity

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

inResumeTopActivity变量防止嵌套执行,最终还是执行resumeTopActivityInnerLocked(prev, options)函数创建activity

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
        //1 没有启动完成直接返回
        if (!mService.mBooting && !mService.mBooted) {
            // Not ready yet!
            return false;
        }
        //2 父activity不是RESUMED状态,子activity也不能resume
        ActivityRecord parent = mActivityContainer.mParentActivity;
        if ((parent != null && parent.state != ActivityState.RESUMED) ||
                !mActivityContainer.isAttachedLocked()) {
            // Do not resume this stack if its parent is not resumed.
            // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
            return false;
        }
        //4 移除topActivity下面全屏activity下面的starting window
        mStackSupervisor.cancelInitializingActivities();

        // Find the first activity that is not finishing.
        //5 这里为焦点stack,最上面的activity也是我们要启动的actvity
        final ActivityRecord next = topRunningActivityLocked();

        // Remember how we'll process this pause/resume situation, and ensure
        // that the state is reset however we wind up proceeding.
        //6 从锁存中拿到userLeaving变量,恢复锁存
        final boolean userLeaving = mStackSupervisor.mUserLeaving;
        mStackSupervisor.mUserLeaving = false;
        //7 在我们这个情景中prev==next
        final TaskRecord prevTask = prev != null ? prev.task : null;
        ......
        next.delayedResume = 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.mWaitingVisibleActivities.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.
        //8 这里全部activity没有pause完成返回false,完成后还会调用该函数
        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);

        // We need to start pausing the current activity so the top one can be resumed...
        final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
        //9 pause非focurestack上的resume activity,这里我们可以知道虽然不再焦点上的activity可见,但是确是pause状态的
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            //10 pause 当前的mResumeActivity
            pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
        }
        if (pausing) {
        //11 我们当前分析的情景需要pause 完成后来处理,所以这里直接返回勒
            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;
        } 
     ........
    }

我们再来总结下这个过程其实很简单那
总结起来就是一步
pause当前所stack上的mResumeActivity.
从目前来看,调用resumeTopActivityUncheckedLocked的只能是焦点stack,
在ActivityStackSupervisor中通过resumeFocusedStackTopActivityLocked函数调用到ActivityStack的resumeTopActivityUncheckedLocked函数,所以只能作用在焦点stack上,所以前面需要先将stack移动到前台才能使用

现在我们来看一下pause的过程
ActivityStack的startPausingLocked函数,函数有四个参数
userLeaving代表是否要执行Activity的onUserLeaving函数
uiSleeping表示是否由于休眠(灭屏)引起的pause
resuming表示即将要resume的activity,也可能为空,不是由于要启动新的activity引起的pause可能为空
dontWait表示不需要等待客户端完成pause,直接善后处理

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean dontWait) {
      ......
      //1 不存在mResumedActivity所以不需要pause ,但是如果没有要resume的activity,要找到一个进行resume
        ActivityRecord prev = mResumedActivity;
        if (prev == null) {
            if (resuming == null) {
                Slog.wtf(TAG, "Trying to pause when nothing is resumed");
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
            return false;
        }
        //2 顶级activity要pause,先搞死子activity
        if (mActivityContainer.mParentActivity == null) {
            // Top level stack, not a child. Look for child stacks.
            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
        }
        ...
        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;
        //3 更新状态为ActivityState.PAUSING
        prev.state = ActivityState.PAUSING;
        prev.task.touchActiveTime();
        clearLaunchTime(prev);
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
        //4 设置mUpdateTaskThumbnailWhenHidden表示要更新在最近任务中显示的任务图片
        if (mService.mHasRecents
                && (next == null || next.noDisplay || next.task != prev.task || 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);
                //5调用客户端进行pause
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            } 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 {
            //6 要pause的activity进程不存在,啥都不干,注意这时候已经不存在mResumeActivity了
            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.
        //7 获取lunch wake lock防止休眠
        if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
            mStackSupervisor.acquireLaunchWakelock();
        }

        if (mPausingActivity != null) {
            //8 已经进入了pause的过程
            // 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) {
                //9 不是由于ui睡眠引起的pause,要停止key的接收
                prev.pauseKeyDispatchingLocked();
            } else if (DEBUG_PAUSE) {
                 Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
            }

            if (dontWait) {
                // If the caller said they don't want to wait for the pause, then complete
                // the pause now.
                //10 不需要等待客户端pause完成进行回调,直接调用completePauseLocked完成清理工作
                completePauseLocked(false, resuming);
                return false;

            } else {
                // Schedule a pause timeout in case the app doesn't respond.
                // We don't give it much time because this directly impacts the
                // responsiveness seen by the user.
                //11 设置一个超时的时间,防止客户端搞事情
                Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
                msg.obj = prev;
                prev.pauseTime = SystemClock.uptimeMillis();
                mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
                return true;
            }

        } else {
            //12 这里面一定是发生了异常,尝试选择一个activity进行resume,指定了resuming就不用管了,否则就请mStackSupervisor选择一个显示
            // 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;
        }
    }

总结一下上面的流程,其实最核心的就是
1 调用客户端进行pause, prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait)
2 获取wake log防止cpu休眠
3 停止接收input event
4 发送一个超时检查消息,防止客户端搞事情

我们来看看ActivityThread这边如何处理

public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            int seq = getLifecycleSeq();
            if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
                    + " operation received seq: " + seq);
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                    configChanges,
                    seq);
        }

对于我们处理的情景是PAUSE_ACTIVITY的消息

  case PAUSE_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, false,
                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
                    maybeSnapshot();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
  private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
        ActivityClientRecord r = mActivities.get(token);
        if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
        //1 检查seq是否已经过期
        if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
            return;
        }
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            if (userLeaving) { //2 执行onUserLeaving函数
                performUserLeavingActivity(r);
            }
            //3 更新config flags
            r.activity.mConfigChangeFlags |= configChanges;
            //4 执行pause
            performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");

            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }

            // Tell the activity manager we have paused.
            if (!dontReport) { //5 dontReport为假报告ams pause完成
                try {
                    ActivityManagerNative.getDefault().activityPaused(token);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }
            mSomeActivitiesChanged = true;
        }
    }
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState, String reason) {
        if (r.paused) {
            if (r.activity.mFinished) { //1 已经finish啥都不返回,否则抛出异常
                // 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) { //2 需要finish设置状态
            r.activity.mFinished = true;
        }

        // Next have the activity save its current state and managed dialogs...
        if (!r.activity.mFinished && saveState) { //3调用OnSaveInstanceState保存数据
            callCallActivityOnSaveInstanceState(r);
        }
        //4 真正调用activity方法
        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++) { //5 通知监听者
            listeners.get(i).onPaused(r.activity);
        }
        //6 返回保存的数据
        return !r.activity.mFinished && saveState ? r.state : null;
    }

函数主要做了一下几步操作
1 保存现场
2 执行pause
3 通知ams, ActivityManagerNative.getDefault().activityPaused(token);

再次回调activityPaused函数中去

 @Override
    public final void activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityPausedLocked(token, false);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

很简单,找到stack,然后调用stack.activityPausedLocked(token, false)函数

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) { //1 移除超时消息
            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)"));
                //2 当前要关闭的activity正是这个activity,完成清理工作
                completePauseLocked(true, null);
                return;
            } else {
                //3 pause 其他activity,更新状态为PAUSED,然后如果需要finish activity,执行
                //finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false)函数
                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);
                        //4 finish activity
                        finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
                    }
                }
            }
        }
        //4 确保activity的可见状态
        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }

注意这并非是timeout的情况处理,这个函数也很简单
1 调用 completePauseLocked(true, null)完成pause状态
2 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 确保activity可见

再来看看completePauseLocked函数,函数有两个参数,boolean resumeNext,代表是否要找到一个activity进行显示
ActivityRecord resuming代表要进行resume 的activity

   private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
        ActivityRecord prev = mPausingActivity;
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);

        if (prev != null) {
            final boolean wasStopping = prev.state == ActivityState.STOPPING;
            prev.state = ActivityState.PAUSED; //1 更新state
            if (prev.finishing) { //2 需要finsih执行finish,我们的情景不会finish
                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);
                 //3 pause 完成不需要等待可见
                if (mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
                    if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                            "Complete pause, no longer waiting: " + prev);
                }
                if (prev.deferRelaunchUntilPaused) {//4 需要重新显示的activity,要到pause才能重新启动
                    // Complete the deferred relaunch that was waiting for pause to complete.
                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
                    relaunchActivityLocked(prev, prev.configChangeFlags, false,
                            prev.preserveWindowOnDeferredRelaunch);
                } else if (wasStopping) { //5 本来是stoping状态的现在变成pause???
                    // 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 = ActivityState.STOPPING;
                } else if ((!prev.visible && !hasVisibleBehindActivity())
                        || mService.isSleepingOrShuttingDownLocked()) {
                    // If we were visible then resumeTopActivities will release resources before
                    // stopping.
                    addToStopping(prev, true /* immediate */);
                }
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
                prev = null;
            }
            // It is possible the activity was freezing the screen before it was paused.
            // In that case go ahead and remove the freeze this activity has on the screen
            // since it is no longer visible.
            if (prev != null) {
                prev.stopFreezingScreenLocked(true /*force*/);
            }
            mPausingActivity = null;
        }

        if (resumeNext) {
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDownLocked()) {
                //4 没有休眠,显示栈顶的activity
                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
            } else {
                mStackSupervisor.checkReadyForSleepLocked();
                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) { //5恢复key的接收
            prev.resumeKeyDispatchingLocked();
            //6 更新电量统计
            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.notifyTaskStackChangedLocked();
            mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
        }
        //7 确保activity的可见性
        mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
    }

这里总结下来如下几步
1 更新activity状态
2 mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
3 统计电量
4 mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);

又一次回到这个调用栈我们已经很熟悉,直接分析ActivityStack的private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) 函数下半部分

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
 ......

        if (prev != null && prev != next) { //1 需要等待下一个activity可见再去stop,添加到
        //mWaitingVisibleActivities中
            if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev)
                    && next != null && !next.nowVisible) {
                mStackSupervisor.mWaitingVisibleActivities.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) { //2 如果要resume的activity已经可见,尽快让pause的activity不可见
                    mWindowManager.setAppVisibility(prev.appToken, false);
                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                            "Not waiting for visible to hide: " + prev + ", waitingVisible="
                            + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
                            + ", nowVisible=" + next.nowVisible);
                } else {
                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                            "Previous already visible but still waiting to hide: " + prev
                            + ", waitingVisible="
                            + mStackSupervisor.mWaitingVisibleActivities.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) {
              ....
                mWindowManager.setAppVisibility(prev.appToken, false);
            } else {
                //3 准备动画
                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.task == next.task
                            ? 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();
        }

        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) { //4注意只有activity被创建后这里app才不为空
          ....
        } else {
            // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) { //5 设置activity已经启动
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    next.showStartingWindow(null, true);
                }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
            }
            //6 启动activity
            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;

到了这里执行比较简单,就是更新activity状态,如果需要finish则finish,另外这里设置了动画,更新了activity动画的状态,最后调用startSpecificActivityLocked函数真心的启动activity,

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
              .......
              //1 进程已经起来直接启动activity
                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.
        }
        //2 进程已经起来,启动进程先,其实启动进程后还是调用resumeTopActivityInnerLocked函数去启动Activity
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

我们跳过进程的启动,这属于进程管理的部分,直接来看启动activity的过程

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {

        if (!allPausedActivitiesComplete()) { //1 没有全部pause完成直接跳过
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "realStartActivityLocked: Skipping start of r=" + r
                    + " some activities pausing...");
            return false;
        }

        if (andResume) { //2 需要显示,先冻结屏幕,注意这里并不一定会冻结,要看config和是否正在冻结过程中
            r.startFreezingScreenLocked(app, 0);
            mWindowManager.setAppVisibility(r.appToken, true);

            // schedule launch ticks to collect information about slow apps.
            r.startLaunchTickingLocked();
        }

        // Have the window manager re-evaluate the orientation of
        // the screen based on the new activity order.  Note that
        // as a result of this, it can call back into the activity
        // manager with a new orientation.  We don't care about that,
        // because the activity is not currently running so we are
        // just restarting it anyway.
        //2 更新config
        if (checkConfig) {
            Configuration config = mWindowManager.updateOrientationFromAppTokens(
                    mService.mConfiguration,
                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
            // Deferring resume here because we're going to launch new activity shortly.
            // We don't want to perform a redundant launch of the same record while ensuring
            // configurations and trying to resume top activity of focused stack.
            mService.updateConfigurationLocked(config, r, false, true /* deferResume */);
        }

      ......
            //3 执行启动
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

         ......
         if (andResume) {
            // As part of the process of launching, ActivityThread also performs
            // a resume.
            //4 resume完成调用
            stack.minimalResumeActivityLocked(r);
        } else {
            // This activity is not starting in the resumed state... which should look like we asked
            // it to pause+stop (but remain visible), and it has done so and reported back the
            // current icicle and other state.
            if (DEBUG_STATES) Slog.v(TAG_STATES,
                    "Moving to PAUSED: " + r + " (starting in paused state)");
            r.state = PAUSED;
        }
        return true;
    }

这个过程客户端的代码有些复杂分析起来占用篇幅比较长,反正就是创建Activity执行生命周期到onResume之后创建ViewRootImpl,DecorView以及添加WindowState到WMS的过程,这里就不去具体说明了,执行完onResume之后就会执行

 ActivityManagerNative.getDefault().activityResumed(token);

函数最终调用到ActivityManagerService中

  @Override
    public final void activityResumed(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityResumedLocked(token);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

这个函数也是比较简单的,最终还是调用到了stack.activityResumedLocked(token)函数

    final void activityResumedLocked(IBinder token) {
        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
        if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
        r.icicle = null;
        r.haveState = false;
    }

何其简单!!!

看完客户端的处理,我们再继续看下realStartActivityLocked的第四个函数ActivityStack的minimalResumeActivityLocked函数

  void minimalResumeActivityLocked(ActivityRecord r) {
        r.state = ActivityState.RESUMED;
        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)"
                + " callers=" + Debug.getCallers(5));
        mResumedActivity = r;
        r.task.touchActiveTime();
        mRecentTasks.addLocked(r.task);
        completeResumeLocked(r);
        mStackSupervisor.checkReadyForSleepLocked();
        setLaunchTime(r);
        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
                "Launch completed; removing icicle of " + r.icicle);
    }

这里重新更新了mResumedActivity,stack上就又存在了resumeActivity,completeResumeLocked函数

 private void completeResumeLocked(ActivityRecord next) {
        next.visible = true;
        next.idle = false;
        next.results = null;
        next.newIntents = null;
        next.stopped = false;

        if (next.isHomeActivity()) {
            ProcessRecord app = next.task.mActivities.get(0).app;
            if (app != null && app != mService.mHomeProcess) {
                mService.mHomeProcess = app;
            }
        }

        if (next.nowVisible) {
            // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
            mStackSupervisor.reportActivityVisibleLocked(next);
            mStackSupervisor.notifyActivityDrawnForKeyguard();
        }

        // schedule an idle timeout in case the app doesn't do it for us.
        //1 安排一个空的超时
        mStackSupervisor.scheduleIdleTimeoutLocked(next);
        //2 报告resume 完成
        mStackSupervisor.reportResumedActivityLocked(next);
        //3 恢复key的分发
        next.resumeKeyDispatchingLocked();
        mNoAnimActivities.clear();

        // Mark the point when the activity is resuming
        // TODO: To be more accurate, the mark should be before the onCreate,
        //       not after the onResume. But for subsequent starts, onResume is fine.
        if (next.app != null) {
            next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid);
        } else {
            next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
        }

        next.returningOptions = null;

        if (getVisibleBehindActivity() == next) {
            // When resuming an activity, require it to call requestVisibleBehind() again.
            setVisibleBehindActivity(null);
        }
    }

boolean reportResumedActivityLocked(ActivityRecord r) {
        final ActivityStack stack = r.task.stack;
        if (isFocusedStack(stack)) {
            mService.updateUsageStats(r, true);
        }
        if (allResumedActivitiesComplete()) {
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            //执行动画
            mWindowManager.executeAppTransition();
            return true;
        }
        return false;
    }

整个流程大概就是这样的记住都是围绕着activity展开的就可以了.其中还穿插了一些WMS相关的显示动画周期相关的函数.我们这里不做重点分析,另外activity的stop函数我们还没有分析到,是因为有一个函数我们还没有进行分析,那就ActivityStackSupervisor类的ensureActivitiesVisibleLocked方法,这个方法有很多地方调用
我们这个流程中有三处会调用到该函数
1 ActivityStackSupervisor的 realStartActivityLocked方法中有这样一段

 if (checkConfig) {
            Configuration config = mWindowManager.updateOrientationFromAppTokens(
                    mService.mConfiguration,
                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
            // Deferring resume here because we're going to launch new activity shortly.
            // We don't want to perform a redundant launch of the same record while ensuring
            // configurations and trying to resume top activity of focused stack.
            mService.updateConfigurationLocked(config, r, false, true /* deferResume */);
        }

更新属性的时候 

2 completeResumeLocked 函数中调用boolean reportResumedActivityLocked(ActivityRecord r)函数
3 private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) 函数中
就这三个地方也是我们情景栈先后顺序
这个函数还是挺关键的

final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows) {
        mTopActivityOccludesKeyguard = false;
        mTopDismissingKeyguardActivity = null;
        mStackSupervisor.mKeyguardController.beginActivityVisibilityUpdate();
        try {
            ActivityRecord top = topRunningActivityLocked();  //1 获取栈上top activity 
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
                    + " configChanges=0x" + Integer.toHexString(configChanges));
            if (top != null) {
                checkTranslucentActivityWaiting(top);
            }

            // If the top activity is not fullscreen, then we need to
            // make sure any activities under it are now visible.
            boolean aboveTop = top != null;
            //2 新启动的Activity是否要被显示
            final int stackVisibility = shouldBeVisible(starting);
            final boolean stackInvisible = stackVisibility != STACK_VISIBLE; //3 该stack不可见
            boolean behindFullscreenActivity = stackInvisible;
            boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this)
                    && (isInStackLocked(starting) == null); //4 如果是焦点stack但是要启动的Activity不在这里面
            boolean behindTranslucentActivity = false; 
            //5 遍历task
            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
                final TaskRecord task = mTaskHistory.get(taskNdx);
                final ArrayList<ActivityRecord> activities = task.mActivities;
                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                    final ActivityRecord r = activities.get(activityNdx);
                    if (r.finishing) {
                        // Normally the screenshot will be taken in makeInvisible(). When an activity
                        // is finishing, we no longer change its visibility, but we still need to take
                        // the screenshots if startPausingLocked decided it should be taken.
                        //6 正在关闭的需要更新缩略图的更新之
                        if (r.mUpdateTaskThumbnailWhenHidden) {
                            r.updateThumbnailLocked(r.screenshotActivityLocked(),
                                    null /* description */);
                            r.mUpdateTaskThumbnailWhenHidden = false;
                        }
                        continue;
                    }
                    final boolean isTop = r == top;
                    if (aboveTop && !isTop) {//7 toppingrunning上面的activity都是不能被显示的直接跳过
                        continue;
                    }
                    aboveTop = false;

                    // Check whether activity should be visible without Keyguard influence
                    final boolean visibleIgnoringKeyguard = r.shouldBeVisibleIgnoringKeyguard(
                            behindFullscreenActivity);
                    r.visibleIgnoringKeyguard = visibleIgnoringKeyguard;
                    //8根据keygurd判断可见性
                    // Now check whether it's really visible depending on Keyguard state.
                    final boolean reallyVisible = checkKeyguardVisibility(r,
                            visibleIgnoringKeyguard, isTop);
                    if (visibleIgnoringKeyguard) {
                        behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
                                behindFullscreenActivity, task, r);
                        if (behindFullscreenActivity && !r.fullscreen) {
                            behindTranslucentActivity = true;
                        }
                    }
                    if (reallyVisible) { //9 真的需要activity可见的情况
                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
                                + " finishing=" + r.finishing + " state=" + r.state);
                        // First: if this is not the current activity being started, make
                        // sure it matches the current configuration.
                        if (r != starting) { //10 因为要显示先更新config
                            r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindows);
                        }

                        if (r.app == null || r.app.thread == null) { //11 进程没有起来或者Activity还没有起来,重新启动
                            if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
                                    resumeNextActivity, r)) {
                                if (activityNdx >= activities.size()) {
                                    // Record may be removed if its process needs to restart.
                                    activityNdx = activities.size() - 1;
                                } else {
                                    resumeNextActivity = false;
                                }
                            }
                        } else if (r.visible) { //12 已经可见
                            // If this activity is already visible, then there is nothing to do here.
                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                                    "Skipping: already visible at " + r);

                            if (r.handleAlreadyVisible()) {
                                resumeNextActivity = false;
                            }
                        } else {
                            //13 不可见 通知window可见
                            r.makeVisibleIfNeeded(starting);
                        }
                        // Aggregate current change flags.
                        configChanges |= r.configChangeFlags;
                    } else {
                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
                                + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible="
                                + stackInvisible + " behindFullscreenActivity="
                                + behindFullscreenActivity + " mLaunchTaskBehind="
                                + r.mLaunchTaskBehind);
                        //14 window不可见的情况
                        makeInvisible(r);
                    }
                }
                if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
                    // The visibility of tasks and the activities they contain in freeform stack are
                    // determined individually unlike other stacks where the visibility or fullscreen
                    // status of an activity in a previous task affects other.
                    behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
                } else if (mStackId == HOME_STACK_ID) {
                    if (task.isHomeTask()) {
                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
                                + " stackInvisible=" + stackInvisible
                                + " behindFullscreenActivity=" + behindFullscreenActivity);
                        // No other task in the home stack should be visible behind the home activity.
                        // Home activities is usually a translucent activity with the wallpaper behind
                        // them. However, when they don't have the wallpaper behind them, we want to
                        // show activities in the next application stack behind them vs. another
                        // task in the home stack like recents.
                        behindFullscreenActivity = true;
                    } else if (task.isRecentsTask()
                            && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) {
                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                                "Recents task returning to app: at " + task
                                        + " stackInvisible=" + stackInvisible
                                        + " behindFullscreenActivity=" + behindFullscreenActivity);
                        // We don't want any other tasks in the home stack visible if the recents
                        // activity is going to be returning to an application activity type.
                        // We do this to preserve the visible order the user used to get into the
                        // recents activity. The recents activity is normally translucent and if it
                        // doesn't have the wallpaper behind it the next activity in the home stack
                        // shouldn't be visible when the home stack is brought to the front to display
                        // the recents activity from an app.
                        behindFullscreenActivity = true;
                    }
                } else if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping after task=" + task
                            + " returning to non-application type=" + task.getTaskToReturnTo());
                    // Once we reach a fullscreen stack task that has a running activity and should
                    // return to another stack task, then no other activities behind that one should
                    // be visible.
                    if (task.topRunningActivityLocked() != null &&
                            task.getTaskToReturnTo() != APPLICATION_ACTIVITY_TYPE) {
                        behindFullscreenActivity = true;
                    }
                }
            }

            if (mTranslucentActivityWaiting != null &&
                    mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
                // Nothing is getting drawn or everything was already visible, don't wait for timeout.
                notifyActivityDrawnLocked(null);
            }
        } finally {
            mStackSupervisor.mKeyguardController.endActivityVisibilityUpdate();
        }
    }

shouldBeVisible 有2种结果STACK_INVISIBLE,
1 STACK_INVISIBLE栈不可见
2 STACK_VISIBLE 栈可见
注意这里描述的是栈的可见性,starting参数只是给计算栈的可见性进行参考

int shouldBeVisible(ActivityRecord starting) {
        if (!isAttached() || mForceHidden) { //1 栈没有attach到Wms上或者强制不可见返回STACK_INVISIBLE表示不可见
            return STACK_INVISIBLE;
        }

        if (mStackSupervisor.isFrontStackOnDisplay(this) || mStackSupervisor.isFocusedStack(this)) { //2 栈在display的前台 或者是焦点栈是可见的
            return STACK_VISIBLE;
        }

        final int stackIndex = mStacks.indexOf(this);

        if (stackIndex == mStacks.size() - 1) {
            Slog.wtf(TAG,
                    "Stack=" + this + " isn't front stack but is at the top of the stack list");
            return STACK_INVISIBLE;
        }

        // Check position and visibility of this stack relative to the front stack on its display.
        final ActivityStack topStack = getTopStackOnDisplay();
        final int topStackId = topStack.mStackId;

        if (mStackId == DOCKED_STACK_ID) {  
            // If the assistant stack is focused and translucent, then the docked stack is always
            // visible
            if (topStack.isAssistantStack()) { //3 当前栈是dockstack,并且最上面的栈是透明且是助手栈则docker stack是可见的
                return (topStack.isStackTranslucent(starting, DOCKED_STACK_ID)) ? STACK_VISIBLE
                        : STACK_INVISIBLE;
            }
            return STACK_VISIBLE;
        }

        // Set home stack to invisible when it is below but not immediately below the docked stack
        // A case would be if recents stack exists but has no tasks and is below the docked stack
        // and home stack is below recents
        if (mStackId == HOME_STACK_ID) { //4 判断home stack的可见性(除非在docker stack下面,否则在其他下面是不可见的)
            int dockedStackIndex = mStacks.indexOf(mStackSupervisor.getStack(DOCKED_STACK_ID));
            if (dockedStackIndex > stackIndex && stackIndex != dockedStackIndex - 1) {
                return STACK_INVISIBLE;
            }
        }

        // Find the first stack behind front stack that actually got something visible.
        int stackBehindTopIndex = mStacks.indexOf(topStack) - 1;
        while (stackBehindTopIndex >= 0 &&
                mStacks.get(stackBehindTopIndex).topRunningActivityLocked() == null) {
            stackBehindTopIndex--;
        }
        final int stackBehindTopId = (stackBehindTopIndex >= 0)
                ? mStacks.get(stackBehindTopIndex).mStackId : INVALID_STACK_ID;
        if (topStackId == DOCKED_STACK_ID || StackId.isAlwaysOnTop(topStackId)) {
            if (stackIndex == stackBehindTopIndex) {
                // Stacks directly behind the docked or pinned stack are always visible.
                //5 在docker后面和pinned后面的堆栈可见
                return STACK_VISIBLE;
            } else if (StackId.isAlwaysOnTop(topStackId) && stackIndex == stackBehindTopIndex - 1) {
                // Otherwise, this stack can also be visible if it is directly behind a docked stack
                // or translucent assistant stack behind an always-on-top top-most stack
                if (stackBehindTopId == DOCKED_STACK_ID) {
                    return STACK_VISIBLE;
                } else if (stackBehindTopId == ASSISTANT_STACK_ID) {
                    return mStacks.get(stackBehindTopIndex).isStackTranslucent(starting, mStackId)
                            ? STACK_VISIBLE : STACK_INVISIBLE;
                }
            }
        }

        if (StackId.isBackdropToTranslucentActivity(topStackId)
                && topStack.isStackTranslucent(starting, stackBehindTopId)) {
            // Stacks behind the fullscreen or assistant stack with a translucent activity are
            // always visible so they can act as a backdrop to the translucent activity.
            // For example, dialog activities
            if (stackIndex == stackBehindTopIndex) {
                return STACK_VISIBLE;
            }
            if (stackBehindTopIndex >= 0) {
                if ((stackBehindTopId == DOCKED_STACK_ID
                        || stackBehindTopId == PINNED_STACK_ID)
                        && stackIndex == (stackBehindTopIndex - 1)) {
                    // The stack behind the docked or pinned stack is also visible so we can have a
                    // complete backdrop to the translucent activity when the docked stack is up.
                    return STACK_VISIBLE;
                }
            }
        }

        if (StackId.isStaticStack(mStackId)) {
            // Visibility of any static stack should have been determined by the conditions above.
            return STACK_INVISIBLE;
        }

        for (int i = stackIndex + 1; i < mStacks.size(); i++) {
            final ActivityStack stack = mStacks.get(i);

            if (!stack.mFullscreen && !stack.hasFullscreenTask()) {
                continue;
            }

            if (!StackId.isDynamicStacksVisibleBehindAllowed(stack.mStackId)) {
                // These stacks can't have any dynamic stacks visible behind them.
                return STACK_INVISIBLE;
            }

            if (!stack.isStackTranslucent(starting, INVALID_STACK_ID)) {
                return STACK_INVISIBLE;
            }
        }

        return STACK_VISIBLE;
    }

使window 不可见

 private void makeInvisible(ActivityRecord r) {
        if (!r.visible) { // 1 当前就是不可见情况直接返回
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
            return;
        }
        // Now for any activities that aren't visible to the user, make sure they no longer are
        // keeping the screen frozen.
        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.state);
        try {
            final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
                    "makeInvisible", true /* beforeStopping */);
            // Defer telling the client it is hidden if it can enter Pip and isn't current paused,
            // stopped or stopping. This gives it a chance to enter Pip in onPause().
            // TODO: There is still a question surrounding activities in multi-window mode that want
            // to enter Pip after they are paused, but are still visible. I they should be okay to
            // enter Pip in those cases, but not "auto-Pip" which is what this condition covers and
            // the current contract for "auto-Pip" is that the app should enter it before onPause
            // returns. Just need to confirm this reasoning makes sense.
            final boolean deferHidingClient = canEnterPictureInPicture
                    && r.state != STOPPING && r.state != STOPPED && r.state != PAUSED;
            r.setDeferHidingClient(deferHidingClient);
            r.setVisible(false); //2 设置不可见

            switch (r.state) {
                case STOPPING:
                case STOPPED: //3 设置window不可见
                    if (r.app != null && r.app.thread != null) {
                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                                "Scheduling invisibility: " + r);
                        r.app.thread.scheduleWindowVisibility(r.appToken, false);
                    }

                    // Reset the flag indicating that an app can enter picture-in-picture once the
                    // activity is hidden
                    r.supportsEnterPipOnTaskSwitch = false;
                    break;

                case INITIALIZING:
                case RESUMED:
                case PAUSING:
                case PAUSED:
                    //4 设置stop状态
                    addToStopping(r, true /* scheduleIdle */,
                            canEnterPictureInPicture /* idleDelayed */);
                    break;

                default:
                    break;
            }
        } catch (Exception e) {
            // Just skip on any failure; we'll make it visible when it next restarts.
            Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e);
        }
    }

void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
        if (!mStackSupervisor.mStoppingActivities.contains(r)) {
            mStackSupervisor.mStoppingActivities.add(r);
        }

        // If we already have a few activities waiting to stop, then give up
        // on things going idle and start clearing them out. Or if r is the
        // last of activity of the last task the stack will be empty and must
        // be cleared immediately.
        boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
                || (r.frontOfTask && mTaskHistory.size() <= 1);
        if (scheduleIdle || forceIdle) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle="
                    + forceIdle + "immediate=" + !idleDelayed);
            if (!idleDelayed) {
                mStackSupervisor.scheduleIdleLocked();
            } else {
                mStackSupervisor.scheduleIdleTimeoutLocked(r);
            }
        } else {
            checkReadyForSleep();
        }
    }

TODO
FLAG_RESUME_WHILE_PAUSING

猜你喜欢

转载自blog.csdn.net/woai110120130/article/details/80297745