ActivityStarter中,生成ActivityRecord之后startActivity方法;

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,            ActivityRecord[] outActivity) {    int result = START_CANCELED;    try {        mService.mWindowManager.deferSurfaceLayout();        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,                startFlags, doResume, options, inTask, outActivity);    } finally {        // If we are not able to proceed, disassociate the activity from the task. Leaving an        // activity in an incomplete state can lead to issues, such as performing operations        // without a window container.        final ActivityStack stack = mStartActivity.getStack();        if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {            stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,                    null /* intentResultData */, "startActivity", true /* oomAdj */);        }        mService.mWindowManager.continueSurfaceLayout();    }    postStartActivityProcessing(r, result, mTargetStack);    return result;}

在AMS的初始化中,SystemServer的startOtherServices方法内,AMS通过setWindowManager方法获得了WindowManagerService;即这里的mService.mWindowManager;

public void setWindowManager(WindowManagerService wm) {    synchronized (this) {        mWindowManager = wm;        mStackSupervisor.setWindowManager(wm);        mLockTaskController.setWindowManager(wm);    }}

WindowManagerService的deferSurfaceLayout方法;通知暂停布局;

/** * Starts deferring layout passes. Useful when doing multiple changes but to optimize * performance, only one layout pass should be done. This can be called multiple times, and * layouting will be resumed once the last caller has called {@link #continueSurfaceLayout} */public void deferSurfaceLayout() {    synchronized (mWindowMap) {        mWindowPlacerLocked.deferLayout();    }}

continueSurfaceLayout方法;恢复暂停的布局;

/** * Resumes layout passes after deferring them. See {@link #deferSurfaceLayout()} */public void continueSurfaceLayout() {    synchronized (mWindowMap) {        mWindowPlacerLocked.continueLayout();    }}

这两个方法中间,是启动Activity的关键方法;startActivityUnchecked;Unchecked这个词很关键,表示再也不会像之前一样,检查个300行代码了;然后这个启动的代码,也有260行之多;

// Note: This method should only be called from {@link startActivity}.private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,        ActivityRecord[] outActivity) {    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,            voiceInteractor);    computeLaunchingTaskFlags();    computeSourceStack();    mIntent.setFlags(mLaunchFlags);    ActivityRecord reusedActivity = getReusableIntentActivity();    int preferredWindowingMode = WINDOWING_MODE_UNDEFINED;    int preferredLaunchDisplayId = DEFAULT_DISPLAY;    if (mOptions != null) {        preferredWindowingMode = mOptions.getLaunchWindowingMode();        preferredLaunchDisplayId = mOptions.getLaunchDisplayId();    }    // windowing mode and preferred launch display values from {@link LaunchParams} take    // priority over those specified in {@link ActivityOptions}.    if (!mLaunchParams.isEmpty()) {        if (mLaunchParams.hasPreferredDisplay()) {            preferredLaunchDisplayId = mLaunchParams.mPreferredDisplayId;        }        if (mLaunchParams.hasWindowingMode()) {            preferredWindowingMode = mLaunchParams.mWindowingMode;        }    }    if (reusedActivity != null) {        // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but        // still needs to be a lock task mode violation since the task gets cleared out and        // the device would otherwise leave the locked task.        if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),                (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {            Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");            return START_RETURN_LOCK_TASK_MODE_VIOLATION;        }        // True if we are clearing top and resetting of a standard (default) launch mode        // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.        final boolean clearTopAndResetStandardLaunchMode =                (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))                        == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)                && mLaunchMode == LAUNCH_MULTIPLE;        // If mStartActivity does not have a task associated with it, associate it with the        // reused activity's task. Do not do so if we're clearing top and resetting for a        // standard launchMode activity.        if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {            mStartActivity.setTask(reusedActivity.getTask());        }        if (reusedActivity.getTask().intent == null) {            // This task was started because of movement of the activity based on affinity...            // Now that we are actually launching it, we can assign the base intent.            reusedActivity.getTask().setIntent(mStartActivity);        }        // This code path leads to delivering a new intent, we want to make sure we schedule it        // as the first operation, in case the activity will be resumed as a result of later        // operations.        if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0                || isDocumentLaunchesIntoExisting(mLaunchFlags)                || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {            final TaskRecord task = reusedActivity.getTask();            // In this situation we want to remove all activities from the task up to the one            // being started. In most cases this means we are resetting the task to its initial            // state.            final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,                    mLaunchFlags);            // The above code can remove {@code reusedActivity} from the task, leading to the            // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The            // task reference is needed in the call below to            // {@link setTargetStackAndMoveToFrontIfNeeded}.            if (reusedActivity.getTask() == null) {                reusedActivity.setTask(task);            }            if (top != null) {                if (top.frontOfTask) {                    // Activity aliases may mean we use different intents for the top activity,                    // so make sure the task now has the identity of the new intent.                    top.getTask().setIntent(mStartActivity);                }                deliverNewIntent(top);            }        }        mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);        reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);        final ActivityRecord outResult =                outActivity != null && outActivity.length > 0 ? outActivity[0] : null;        // When there is a reused activity and the current result is a trampoline activity,        // set the reused activity as the result.        if (outResult != null && (outResult.finishing || outResult.noDisplay)) {            outActivity[0] = reusedActivity;        }        if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {            // We don't need to start a new activity, and the client said not to do anything            // if that is the case, so this is it!  And for paranoia, make sure we have            // correctly resumed the top activity.            resumeTargetStackIfNeeded();            return START_RETURN_INTENT_TO_CALLER;        }        if (reusedActivity != null) {            setTaskFromIntentActivity(reusedActivity);            if (!mAddingToTask && mReuseTask == null) {                // We didn't do anything...  but it was needed (a.k.a., client don't use that                // intent!)  And for paranoia, make sure we have correctly resumed the top activity.                resumeTargetStackIfNeeded();                if (outActivity != null && outActivity.length > 0) {                    outActivity[0] = reusedActivity;                }                return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;            }        }    }    if (mStartActivity.packageName == null) {        final ActivityStack sourceStack = mStartActivity.resultTo != null                ? mStartActivity.resultTo.getStack() : null;        if (sourceStack != null) {            sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,                    mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,                    null /* data */);        }        ActivityOptions.abort(mOptions);        return START_CLASS_NOT_FOUND;    }    // If the activity being launched is the same as the one currently at the top, then    // we need to check if it should only be launched once.    final ActivityStack topStack = mSupervisor.mFocusedStack;    final ActivityRecord topFocused = topStack.getTopActivity();    final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);    final boolean dontStart = top != null && mStartActivity.resultTo == null            && top.realActivity.equals(mStartActivity.realActivity)            && top.userId == mStartActivity.userId            && top.app != null && top.app.thread != null            && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0            || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));    if (dontStart) {        // For paranoia, make sure we have correctly resumed the top activity.        topStack.mLastPausedActivity = null;        if (mDoResume) {            mSupervisor.resumeFocusedStackTopActivityLocked();        }        ActivityOptions.abort(mOptions);        if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {            // We don't need to start a new activity, and the client said not to do            // anything if that is the case, so this is it!            return START_RETURN_INTENT_TO_CALLER;        }        deliverNewIntent(top);        // Don't use mStartActivity.task to show the toast. We're not starting a new activity        // but reusing 'top'. Fields in mStartActivity may not be fully initialized.        mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,                preferredLaunchDisplayId, topStack);        return START_DELIVERED_TO_TOP;    }    boolean newTask = false;    final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)            ? mSourceRecord.getTask() : null;    // Should this be considered a new task?    int result = START_SUCCESS;    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {        newTask = true;        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);    } else if (mSourceRecord != null) {        result = setTaskFromSourceRecord();    } else if (mInTask != null) {        result = setTaskFromInTask();    } else {        // This not being started from an existing activity, and not part of a new task...        // just put it in the top task, though these days this case should never happen.        setTaskToCurrentTopOrCreateNewTask();    }    if (result != START_SUCCESS) {        return result;    }    mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,            mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);    mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,            mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));    if (newTask) {        EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,                mStartActivity.getTask().taskId);    }    ActivityStack.logStartActivity(            EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());    mTargetStack.mLastPausedActivity = null;    mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,            mOptions);    if (mDoResume) {        final ActivityRecord topTaskActivity =                mStartActivity.getTask().topRunningActivityLocked();        if (!mTargetStack.isFocusable()                || (topTaskActivity != null && topTaskActivity.mTaskOverlay                && mStartActivity != topTaskActivity)) {            // If the activity is not focusable, we can't resume it, but still would like to            // make sure it becomes visible as it starts (this will also trigger entry            // animation). An example of this are PIP activities.            // Also, we don't want to resume activities in a task that currently has an overlay            // as the starting activity just needs to be in the visible paused state until the            // over is removed.            mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);            // Go ahead and tell window manager to execute app transition for this activity            // since the app transition will not be triggered through the resume channel.            mService.mWindowManager.executeAppTransition();        } else {            // If the target stack was not previously focusable (previous top running activity            // on that stack was not visible) then any prior calls to move the stack to the            // will not update the focused stack.  If starting the new activity now allows the            // task stack to be focusable, then ensure that we now update the focused stack            // accordingly.            if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {                mTargetStack.moveToFront("startActivityUnchecked");            }            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,                    mOptions);        }    } else if (mStartActivity != null) {        mSupervisor.mRecentTasks.add(mStartActivity.getTask());    }    mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,            preferredLaunchDisplayId, mTargetStack);    return START_SUCCESS;}

代码太长;只能一段段分开看;

1. 启动参数的初始化;里面是对一个参数和Flag的设置;

setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,        voiceInteractor);

2. 计算LaunchingTask和一些LaunchMode;

computeLaunchingTaskFlags();

3. 拿到mSourceStack;这里会对正在关闭的source做特殊处理;

computeSourceStack();

4. 设置LaunchFlags;FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_MULTIPLE_TASK等Flags;

mIntent.setFlags(mLaunchFlags);

5. 判断是否应将新Activity插入现有task;如果不是,则返回null;如果是,则返回包含要添加新Activity的task的ActivityRecord;

ActivityRecord reusedActivity = getReusableIntentActivity();

6. window mode和dispaly id;window mode定义在WindowConfiguration,包括WINDOWING_MODE_UNDEFINED、WINDOWING_MODE_FULLSCREEN、WINDOWING_MODE_PINNED等;display id相关定义在Display中,每个dispay都有一个唯一的id;

int preferredWindowingMode = WINDOWING_MODE_UNDEFINED;int preferredLaunchDisplayId = DEFAULT_DISPLAY;if (mOptions != null) {    preferredWindowingMode = mOptions.getLaunchWindowingMode();    preferredLaunchDisplayId = mOptions.getLaunchDisplayId();}// windowing mode and preferred launch display values from {@link LaunchParams} take// priority over those specified in {@link ActivityOptions}.if (!mLaunchParams.isEmpty()) {    if (mLaunchParams.hasPreferredDisplay()) {        preferredLaunchDisplayId = mLaunchParams.mPreferredDisplayId;    }    if (mLaunchParams.hasWindowingMode()) {        preferredWindowingMode = mLaunchParams.mWindowingMode;    }}

7. 重用Activity;符合条件就直接重用;不走后面的代码;

if (reusedActivity != null) {    // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but    // still needs to be a lock task mode violation since the task gets cleared out and    // the device would otherwise leave the locked task.    if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),            (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {        Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");        return START_RETURN_LOCK_TASK_MODE_VIOLATION;    }    // True if we are clearing top and resetting of a standard (default) launch mode    // ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.    final boolean clearTopAndResetStandardLaunchMode =            (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))                    == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)            && mLaunchMode == LAUNCH_MULTIPLE;    // If mStartActivity does not have a task associated with it, associate it with the    // reused activity's task. Do not do so if we're clearing top and resetting for a    // standard launchMode activity.    if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {        mStartActivity.setTask(reusedActivity.getTask());    }    if (reusedActivity.getTask().intent == null) {        // This task was started because of movement of the activity based on affinity...        // Now that we are actually launching it, we can assign the base intent.        reusedActivity.getTask().setIntent(mStartActivity);    }    // This code path leads to delivering a new intent, we want to make sure we schedule it    // as the first operation, in case the activity will be resumed as a result of later    // operations.    if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0            || isDocumentLaunchesIntoExisting(mLaunchFlags)            || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {        final TaskRecord task = reusedActivity.getTask();        // In this situation we want to remove all activities from the task up to the one        // being started. In most cases this means we are resetting the task to its initial        // state.        final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,                mLaunchFlags);        // The above code can remove {@code reusedActivity} from the task, leading to the        // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The        // task reference is needed in the call below to        // {@link setTargetStackAndMoveToFrontIfNeeded}.        if (reusedActivity.getTask() == null) {            reusedActivity.setTask(task);        }        if (top != null) {            if (top.frontOfTask) {                // Activity aliases may mean we use different intents for the top activity,                // so make sure the task now has the identity of the new intent.                top.getTask().setIntent(mStartActivity);            }            deliverNewIntent(top);        }    }    mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);    reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);    final ActivityRecord outResult =            outActivity != null && outActivity.length > 0 ? outActivity[0] : null;    // When there is a reused activity and the current result is a trampoline activity,    // set the reused activity as the result.    if (outResult != null && (outResult.finishing || outResult.noDisplay)) {        outActivity[0] = reusedActivity;    }    if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {        // We don't need to start a new activity, and the client said not to do anything        // if that is the case, so this is it!  And for paranoia, make sure we have        // correctly resumed the top activity.        resumeTargetStackIfNeeded();        return START_RETURN_INTENT_TO_CALLER;    }    if (reusedActivity != null) {        setTaskFromIntentActivity(reusedActivity);        if (!mAddingToTask && mReuseTask == null) {            // We didn't do anything...  but it was needed (a.k.a., client don't use that            // intent!)  And for paranoia, make sure we have correctly resumed the top activity.            resumeTargetStackIfNeeded();            if (outActivity != null && outActivity.length > 0) {                outActivity[0] = reusedActivity;            }            return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;        }    }}

8. 检查class not found;

if (mStartActivity.packageName == null) {    final ActivityStack sourceStack = mStartActivity.resultTo != null            ? mStartActivity.resultTo.getStack() : null;    if (sourceStack != null) {        sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,                mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,                null /* data */);    }    ActivityOptions.abort(mOptions);    return START_CLASS_NOT_FOUND;}

9. 对SINGLE_TOP做的CASE处理;

// If the activity being launched is the same as the one currently at the top, then// we need to check if it should only be launched once.final ActivityStack topStack = mSupervisor.mFocusedStack;final ActivityRecord topFocused = topStack.getTopActivity();final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);final boolean dontStart = top != null && mStartActivity.resultTo == null        && top.realActivity.equals(mStartActivity.realActivity)        && top.userId == mStartActivity.userId        && top.app != null && top.app.thread != null        && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0        || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));if (dontStart) {    // For paranoia, make sure we have correctly resumed the top activity.    topStack.mLastPausedActivity = null;    if (mDoResume) {        mSupervisor.resumeFocusedStackTopActivityLocked();    }    ActivityOptions.abort(mOptions);    if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {        // We don't need to start a new activity, and the client said not to do        // anything if that is the case, so this is it!        return START_RETURN_INTENT_TO_CALLER;    }    deliverNewIntent(top);    // Don't use mStartActivity.task to show the toast. We're not starting a new activity    // but reusing 'top'. Fields in mStartActivity may not be fully initialized.    mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,            preferredLaunchDisplayId, topStack);    return START_DELIVERED_TO_TOP;}

10. 根据情况选择task,并将其带到前台;如果是new task,就需要创建新的;

boolean newTask = false;final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)        ? mSourceRecord.getTask() : null;// Should this be considered a new task?int result = START_SUCCESS;if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask        && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {    newTask = true;    result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);} else if (mSourceRecord != null) {    result = setTaskFromSourceRecord();} else if (mInTask != null) {    result = setTaskFromInTask();} else {    // This not being started from an existing activity, and not part of a new task...    // just put it in the top task, though these days this case should never happen.    setTaskToCurrentTopOrCreateNewTask();}if (result != START_SUCCESS) {    return result;}

11. 给予UriPermission;

mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,        mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);

12. emmm

mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,        mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));

13. 打LOG

if (newTask) {    EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,            mStartActivity.getTask().taskId);}ActivityStack.logStartActivity(        EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());

14. 将mLastPausedActivity 置为null;

mTargetStack.mLastPausedActivity = null;
/** * This is the last activity that we put into the paused state.  This is * used to determine if we need to do an activity transition while sleeping, * when we normally hold the top activity paused. */ActivityRecord mLastPausedActivity = null;

15. emmmm

mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);

16. 启动Activity

mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,        mOptions);

17. Resume

if (mDoResume) {    final ActivityRecord topTaskActivity =            mStartActivity.getTask().topRunningActivityLocked();    if (!mTargetStack.isFocusable()            || (topTaskActivity != null && topTaskActivity.mTaskOverlay            && mStartActivity != topTaskActivity)) {        // If the activity is not focusable, we can't resume it, but still would like to        // make sure it becomes visible as it starts (this will also trigger entry        // animation). An example of this are PIP activities.        // Also, we don't want to resume activities in a task that currently has an overlay        // as the starting activity just needs to be in the visible paused state until the        // over is removed.        mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);        // Go ahead and tell window manager to execute app transition for this activity        // since the app transition will not be triggered through the resume channel.        mService.mWindowManager.executeAppTransition();    } else {        // If the target stack was not previously focusable (previous top running activity        // on that stack was not visible) then any prior calls to move the stack to the        // will not update the focused stack.  If starting the new activity now allows the        // task stack to be focusable, then ensure that we now update the focused stack        // accordingly.        if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {            mTargetStack.moveToFront("startActivityUnchecked");        }        mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,                mOptions);    }} else if (mStartActivity != null) {    mSupervisor.mRecentTasks.add(mStartActivity.getTask());}

18. 更新stack的userId

mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
/** * Update the last used stack id for non-current user (current user's last * used stack is the focused stack) */void updateUserStackLocked(int userId, ActivityStack stack) {    if (userId != mCurrentUser) {        mUserStackInFront.put(userId, stack != null ? stack.getStackId() : mHomeStack.mStackId);    }}

19. 处理分屏

mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,        preferredLaunchDisplayId, mTargetStack);

 

startActivityUnchecked的内容很多;后面再摘取有趣的部分深入的阅读;

mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,                mOptions);
targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);mFocusedStack.resumeTopActivityUncheckedLocked(null, null);private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options)
mStackSupervisor.startSpecificActivityLocked(next, true, true);final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,            boolean andResume, boolean checkConfig) throws RemoteException

 

更多相关文章

  1. Android MediaServer初始化流程
  2. Android Audio代码分析14 - testPlaybackHeadPositionIncrease
  3. Android PackageManager 卸载包的方法
  4. Android实现定时器的方法
  5. Android播放音乐方法
  6. Android kill app Process 结束进程代码
  7. 阻止dialog消失的方法 (Android Platform)
  8. Android 工具代码

随机推荐

  1. android 随笔
  2. 二之番外.Android六种布局详细讲解
  3. 修改Android开机画面
  4. 基于Android(安卓)6.0修改的音乐播放器可
  5. 编译 Android版本的Openal方式
  6. Android通过AudioFocus机制对音频焦点进
  7. Android:Bitmap->Drawble->Byte[]
  8. 关于android studio出现Gradle sync fail
  9. Maven For Android插件安装
  10. android 打开移动数据流程