Android應(yīng)用程序組件Activity的"singleTask"(8)
這個(gè)函數(shù)無非就是根據(jù)即將要啟動(dòng)的SubActivity的taskAffinity屬性值在系統(tǒng)中查找這樣的一個(gè)Task:Task的affinity 屬性值與即將要啟動(dòng)的Activity的taskAffinity屬性值一致。
如果存在,就返回這個(gè)Task堆棧頂端的Activity回去。
在上面的 AndroidManifest.xml文件中,沒有配置MainActivity和SubActivity的taskAffinity屬性,于是它們的 taskAffinity屬性值就默認(rèn)為父標(biāo)簽application的taskAffinity屬性值,這里,標(biāo)簽application的 taskAffinity也沒有配置,于是它們就默認(rèn)為包名,即"shy.luo.task"。
由于在啟動(dòng)SubActivity之 前,MainActivity已經(jīng)啟動(dòng),MainActivity啟動(dòng)的時(shí)候,會(huì)在一個(gè)新的任務(wù)里面啟動(dòng),而這個(gè)新的任務(wù)的affinity屬性就等于它 的***個(gè)Activity的taskAffinity屬性值。
于是,這個(gè)函數(shù)會(huì)動(dòng)回表示MainActivity的ActivityRecord回去.
回到前面的startActivityUncheckedLocked函數(shù)中,這里的taskTop就表示MainActivity,它不為 null,于是繼續(xù)往前執(zhí)行。由于條件r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK成立,于是執(zhí)行下面語句:
- [java] view plaincopyActivityRecord top = performClearTaskLocked(
- kTop.task.taskId, r, launchFlags, true);
函數(shù)performClearTaskLocked也是定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
- [java] view plaincopypublic 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;
- }
- ......
- }