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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TangGeeA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值