这个函数无非就是根据即将要启动的SubActivity的taskAffinity属性值在系统中查找这样的一个Task:Task的affinity属性值与即将要启动的Activity的taskAffinity属性值一致。如果存在,就返回这个Task堆栈顶端的Activity回去。在上面的AndroidManifest.xml文件中,没有配置MainActivity和SubActivity的taskAffinity属性,于是它们的taskAffinity属性值就默认为父标签application的taskAffinity属性值,这里,标签application的taskAffinity也没有配置,于是它们就默认为包名,即"shy.luo.task"。由于在启动SubActivity之前,MainActivity已经启动,MainActivity启动的时候,会在一个新的任务里面启动,而这个新的任务的affinity属性就等于它的第一个Activity的taskAffinity属性值。于是,这个函数会动回表示MainActivity的ActivityRecord回去.
回到前面的startActivityUncheckedLocked函数中,这里的taskTop就表示MainActivity,它不为null,于是继续往前执行。由于条件r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK成立,于是执行下面语句:
ActivityRecord top = performClearTaskLocked( kTop.task.taskId, r, launchFlags, true);
函数performClearTaskLocked也是定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
public class ActivityStack { ...... /** * Perform clear operation as requested by * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the * stack to the given task, then look for * an instance of that activity in the stack and, if found, finish all * activities on top of it and return the instance. * * @param newR Description of the new activity being started. * @return Returns the old activity that should be continue to be used, * or null if none was found. */ private final ActivityRecord performClearTaskLocked(int taskId, ActivityRecord newR, int launchFlags, boolean doClear) { int i = mHistory.size(); // First find the requested task. while (i > 0) { i--; ActivityRecord r = (ActivityRecord)mHistory.get(i); if (r.task.taskId == taskId) { i++; break; } } // Now clear it. while (i > 0) { i--; ActivityRecord r = (ActivityRecord)mHistory.get(i); if (r.finishing) { continue; } if (r.task.taskId != taskId) { return null; } if (r.realActivity.equals(newR.realActivity)) { // Here it is! Now finish everything in front... ActivityRecord ret = r; if (doClear) { while (i < (mHistory.size()-1)) { i++; r = (ActivityRecord)mHistory.get(i); if (r.finishing) { continue; } if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "clear")) { i--; } } } // Finally, if this is a normal launch mode (that is, not // expecting onNewIntent()), then we will finish the current // instance of the activity so a new fresh one can be started. if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { if (!ret.finishing) { int index = indexOfTokenLocked(ret); if (index >= 0) { finishActivityLocked(ret, index, Activity.RESULT_CANCELED, null, "clear"); } return null; } } return ret; } } return null; } ...... } 这个函数中作用无非就是找到ID等于参数taskId的任务,然后在这个任务中查找是否已经存在即将要启动的Activity的实例,如果存在,就会把这个Actvity实例上面直到任务堆栈顶端的Activity通过调用finishActivityLocked函数将它们结束掉。在这个例子中,就是要在属性值affinity等于"shy.luo.task"的任务中看看是否存在SubActivity类型的实例,如果有,就把它上面的Activity都结束掉。这里,属性值affinity等于"shy.luo.task"的任务只有一个MainActivity,而且它不是SubActivity的实例,所以这个函数就返回null了。
回到前面的startActivityUncheckedLocked函数中,这里的变量top就为null了,于是执行下面的else语句:
if (top != null) { ...... } else { // A special case: we need to // start the activity because it is not currently // running, and the caller has asked to clear the // current task to have this activity at the top. addingToTask = true; // Now pretend like this activity is being started // by the top of its task, so it is put in the // right place. sourceRecord = taskTop; }
于是,变量addingToTask值就为true了,同时将变量sourceRecord的值设置为taskTop,即前面调用findTaskLocked函数的返回值,这里,它就是表示MainActivity了。继续往下看,下面这个if语句:
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)) { if (top.app != null && top.app.thread != null) { ...... } } } } else { ...... }
它是例行性地检查当前任务顶端的Activity,是否是即将启动的Activity的实例,如果是否的话,在某些情况下,它什么也不做,就结束这个函数调用了。这里,当前任务顶端的Activity为MainActivity,它不是SubActivity实例,于是继续往下执行:boolean newTask = false; // Should this be considered a new task? if (r.resultTo == null && !addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { ...... } else if (sourceRecord != null) { if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { ...... } else if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { ...... } // 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. r.task = sourceRecord.task; ...... } else { ...... }
这里首先将newTask变量初始化为false,表示不要在新的任务中启动这个SubActivity。由于前面的已经把addingToTask设置为true,因此,这里会执行中间的else if语句,即这里会把r.task设置为sourceRecord.task,即把SubActivity放在MainActivity所在的任务中启动。