由于在这个例子的AndroidManifest.xml文件中,MainActivity没有配置launchMode属值,因此,这里的r.launchMode为默认值0,表示以标准(Standard,或者称为ActivityInfo.LAUNCH_MULTIPLE)的方式来启动这个Activity。Activity的启动方式有四种,其余三种分别是ActivityInfo.LAUNCH_SINGLE_INSTANCE、ActivityInfo.LAUNCH_SINGLE_TASK和ActivityInfo.LAUNCH_SINGLE_TOP,具体可以参考官方网站。
传进来的参数r.resultTo为null,表示Launcher不需要等这个即将要启动的MainActivity的执行结果。
由于这个intent的标志值的位Intent.FLAG_ACTIVITY_NEW_TASK被置位,而且Intent.FLAG_ACTIVITY_MULTIPLE_TASK没有置位,因此,下面的if语句会被执行:
if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { // If bring to front is requested, and no result is requested, and // we can find a task that was started with this same // component, then instead of launching bring that one to the front. if (r.resultTo == null) { // See if there is a task to bring to the front. If this is // a SINGLE_INSTANCE activity, there can be one and only one // instance of it in the history, and it is always in its own // unique task, so we do a special search. ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE ? findTaskLocked(intent, r.info) : findActivityLocked(intent, r.info); if (taskTop != null) { ...... } } }这段代码的逻辑是查看一下,当前有没有Task可以用来执行这个Activity。由于r.launchMode的值不为ActivityInfo.LAUNCH_SINGLE_INSTANCE,因此,它通过findTaskLocked函数来查找存不存这样的Task,这里返回的结果是null,即taskTop为null,因此,需要创建一个新的Task来启动这个Activity。
接着往下看:
if (r.packageName != null) { // 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. ActivityRecord top = topRunningNonDelayedActivityLocked(notTop); if (top != null && r.resultTo == null) { if (top.realActivity.equals(r.realActivity)) { ...... } } }
这段代码的逻辑是看一下,当前在堆栈顶端的Activity是否就是即将要启动的Activity,有些情况下,如果即将要启动的Activity就在堆栈的顶端,那么,就不会重新启动这个Activity的别一个实例了,具体可以参考官方网站。现在处理堆栈顶端的Activity是Launcher,与我们即将要启动的MainActivity不是同一个Activity,因此,这里不用进一步处理上述介绍的情况。
执行到这里,我们知道,要在一个新的Task里面来启动这个Activity了,于是新创建一个Task:
if (r.resultTo == null && !addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { // todo: should do better management of integers. mService.mCurTask++; if (mService.mCurTask <= 0) { mService.mCurTask = 1; } r.task = new TaskRecord(mService.mCurTask, r.info, intent, (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); ...... newTask = true; if (mMainStack) { mService.addRecentTaskLocked(r.task); } }新建的Task保存在r.task域中,同时,添加到mService中去,这里的mService就是ActivityManagerService了。
最后就进入startActivityLocked(r, newTask, doResume)进一步处理了。这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
public class ActivityStack { ...... private final void startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume) { final int NH = mHistory.size(); int addPos = -1; if (!newTask) { ...... } // Place a new activity at top of stack, so it is next to interact // with the user. if (addPos < 0) { addPos = NH; } // If we are not placing the new activity frontmost, we do not want // to deliver the onUserLeaving callback to the actual frontmost // activity if (addPos < NH) { ...... } // Slot the activity into the history stack and proceed mHistory.add(addPos, r); r.inHistory = true; r.frontOfTask = newTask; r.task.numActivities++; if (NH > 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. ...... } else { // If this is the first activity, don't do any fancy animations, // because there is nothing for it to animate on top of. ...... } ...... if (doResume) { resumeTopActivityLocked(null); } } ...... }
这里的NH表示当前系统中历史任务的个数,这里肯定是大于0,因为Launcher已经跑起来了。当NH>0时,并且现在要切换新任务时,要做一些任务切的界面操作,这段代码我们就不看了,这里不会影响到下面启Activity的过程,有兴趣的读取可以自己研究一下。
这里传进来的参数doResume为true,于是调用resumeTopActivityLocked进一步操作。