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判断一个应用是不是系统应用
  2. Android实现定时器的方法
  3. Android(安卓)PackageManager 卸载包的方法
  4. Android在子线程中更新UI(二)
  5. android中如何获取视频时长
  6. Android(安卓)Audio代码分析14 - testPlaybackHeadPositionIncre
  7. Android重写view时onAttachedToWindow () 和 onDetachedFromWind
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. 在Android上做List Remove的时候遇到的异
  2. android adb shel l命令使用 解决 Read-o
  3. Android(安卓)Studio与 Android(安卓)SDK
  4. Android用http协议上传文件
  5. 第一篇 GridView控件
  6. Android(安卓)CollapsingToolbarLayout:将
  7. Android资源管理框架-------之总述(一)
  8. android设置wallpaper
  9. 读取SIM卡信息
  10. First Android(安卓)application