Task
官方文檔 ?中關(guān)于task的解釋:
任務(wù)是指在執(zhí)行特定作業(yè)時與用戶交互的一系列 Activity订讼。 這些 Activity 按照各自的打開順序排列在堆棧(即返回棧)中据忘。
task是可以跨應(yīng)用的舰涌,這正是task存在的一個重要原因。有的Activity,雖然不在同一個app中帮坚,但為了保持用戶操作的連貫性踩身,把他們放在同一個任務(wù)中。例如吐句,在我們的應(yīng)用中的一個Activity A中點擊發(fā)送郵件胁后,會啟動郵件程序的一個Activity B來發(fā)送郵件,這兩個activity是存在于不同app中的嗦枢,但是被系統(tǒng)放在一個任務(wù)中攀芯,這樣當(dāng)發(fā)送完郵件后,用戶按back鍵返回文虏,可以返回到原來的Activity A中侣诺,這樣就確保了用戶體驗。
Lunch mode
1.android:launchMode
"standard"(默認(rèn)模式)
默認(rèn)氧秘。系統(tǒng)在啟動 Activity 的任務(wù)中創(chuàng)建 Activity 的新實例并向其傳送 Intent年鸳。Activity 可以多次實例化,而每個實例均可屬于不同的任務(wù)丸相,并且一個任務(wù)可以擁有多個實例
在這種模式下啟動的activity可以被多次實例化搔确,即在同一個任務(wù)中可以存在多個activity的實例,每個實例都會處理一個Intent對象灭忠。如果Activity A的啟動模式為standard妥箕,并且A已經(jīng)啟動,在A中再次啟動Activity A更舞,即調(diào)用startActivity(new Intent(this畦幢,A.class)),會在A的上面再次啟動一個A的實例缆蝉,即當(dāng)前的桟中的狀態(tài)為A-->A宇葱。
"singleTop"
如果當(dāng)前任務(wù)的頂部已存在 Activity 的一個實例,則系統(tǒng)會通過調(diào)用該實例的onNewIntent()方法向其傳送 Intent刊头,而不是創(chuàng)建 Activity 的新實例黍瞧。Activity 可以多次實例化,而每個實例均可屬于不同的任務(wù)原杂,并且一個任務(wù)可以擁有多個實例(但前提是位于返回棧頂部的 Activity 并不是 Activity 的現(xiàn)有實例)印颤。
如果A的啟動模式為singleTop,并且A的一個實例已經(jīng)存在于棧頂中穿肄,再次啟動A時年局,不會再次創(chuàng)建A的實例际看,而是重用原來的實例,并且調(diào)用原來實例的onNewIntent()方法矢否。任務(wù)桟中還是這有一個A的實例仲闽。
如果以singleTop模式啟動的activity的一個實例已經(jīng)存在與任務(wù)桟中,但是不在桟頂僵朗,那么它的行為和standard模式相同赖欣,也會創(chuàng)建多個實例。
"singleTask"
系統(tǒng)創(chuàng)建新任務(wù)并實例化位于新任務(wù)底部的 Activity验庙。但是顶吮,如果該 Activity 的一個實例已存在于一個單獨的任務(wù)中,則系統(tǒng)會通過調(diào)用現(xiàn)有實例的onNewIntent()方法向其傳送 Intent粪薛,而不是創(chuàng)建新實例悴了。一次只能存在 Activity 的一個實例。
在同一個任務(wù)中具有唯一性汗菜,至于會不會開啟新的任務(wù)與taskAffinity有關(guān)。
taskAffinity: Activity 有著親和關(guān)系的任務(wù)挑社。從概念上講陨界,具有相同親和關(guān)系的 Activity 歸屬同一任務(wù)(從用戶的角度來看,則是歸屬同一“應(yīng)用”)痛阻。 任務(wù)的親和關(guān)系由其根 Activity 的親和關(guān)系確定菌瘪。
如果沒有對activity設(shè)置該屬性的話,默認(rèn)為application的*taskAffinity*,如果application也沒有設(shè)置,則為app的包名阱当。
啟動一個singleTask模式的activity俏扩,會首先在系統(tǒng)中找與它的taskAffinity屬性一致的任務(wù)棧
????1.沒有特別指定taskAffinity,則為當(dāng)前的task
? ? 2.如果指定了taskAffinity弊添,先在系統(tǒng)中查找task录淡,如果找不到則創(chuàng)建一個新的task,將activity作為root放置其中油坝。
????3.如果要啟動的Activity已經(jīng)存在嫉戚、但沒有位于Task棧頂,系統(tǒng)會將把位于該Activity上面所有Activity移出Task澈圈,從而使其轉(zhuǎn)入棧頂彬檀。在該Activity之下的不變。
????a1->a2->a3->a1, a1 按back瞬女,直接退出窍帝,不會回到a3.
????4.如果需要在新的任務(wù)棧中啟動,就需要為activity設(shè)置獨立的taskAffinity.
? ? 5.如果當(dāng)前activity是在新的任務(wù)棧中打開的話,那么之后在該activity中通過默認(rèn)方式啟動的activity都在這個新的任務(wù)棧。
"singleInstance"
與?"singleTask"?相同诽偷,只是系統(tǒng)不會將任何其他 Activity 啟動到包含實例的任務(wù)中坤学。該 Activity 始終是其任務(wù)唯一僅有的成員疯坤;由此 Activity 啟動的任何 Activity 均在單獨的任務(wù)中打開。
????1.具有全局唯一性拥峦,即整個系統(tǒng)中只會存在一個這樣的實例
? ? 2.具有獨占性贴膘,即它會獨自占用一個任務(wù),被他開啟的任何activity都會運行在其他任務(wù)中略号。
? ? 3.被singleInstance模式的Activity開啟的其他activity刑峡,能夠開啟一個新任務(wù),但不一定開啟新的任務(wù)玄柠,也可能在已有的一個任務(wù)中開啟(根據(jù)taskAffinity)突梦。
2.Intent flag
啟動 Activity 時,您可以通過在傳遞給startActivity()的 Intent 中加入相應(yīng)的標(biāo)志羽利,修改 Activity 與其任務(wù)的默認(rèn)關(guān)聯(lián)方式宫患。可用于修改默認(rèn)行為的標(biāo)志包括:
在新任務(wù)中啟動 Activity这弧。如果已為正在啟動的 Activity 運行任務(wù)娃闲,則該任務(wù)會轉(zhuǎn)到前臺并恢復(fù)其最后狀態(tài),同時 Activity 會在onNewIntent()中收到新 Intent
類似singleTask匾浪。
如果正在啟動的 Activity 是當(dāng)前 Activity(位于返回棧的頂部)皇帮,則 現(xiàn)有實例會接收對onNewIntent()的調(diào)用,而不是創(chuàng)建 Activity 的新實例蛋辈。
相當(dāng)于launchMode中的singleTop属拾,比如說原來棧中情況是A,B,C,D,在D中啟動D(加入該flag),棧中的情況還是A,B,C,D
如果正在啟動的 Activity 已在當(dāng)前任務(wù)中運行冷溶,則會銷毀當(dāng)前任務(wù)頂部的所有 Activity渐白,并通過onNewIntent()將此 Intent 傳遞給 Activity 已恢復(fù)的實例(現(xiàn)在位于頂部),而不是啟動該 Activity 的新實例逞频。
假設(shè)有A,B兩個Activity纯衍,在AndroidManifest.xml中將A Activity的設(shè)置了android:clearTaskOnLaunch="true"。然后A中的操作啟動了B苗胀,進(jìn)入了B:(1)如果此時用戶按了Home鍵回到主屏幕上托酸,然后又點擊了主屏幕上的A的icon圖標(biāo)啟動應(yīng)用。那么此時不是進(jìn)入B柒巫,而是進(jìn)入了A励堡。(2)如果用戶按了屏幕下方的”最近任務(wù)列表“鍵,調(diào)出最近任務(wù)列表中堡掏,出現(xiàn)的是B应结,用戶點擊,此時又進(jìn)入的是B。
參考
Android中Activity四種啟動模式和taskAffinity屬性詳解
Activity的任務(wù)棧Task以及啟動模式與Intent的Flag詳解
https://developer.android.com/guide/components/tasks-and-back-stack.html