http://www.cnblogs.com/mengdd/archive/2013/06/13/3134380.html

Task是使用者在進行某項工作時需要與之互動的一系列activities的集合。這些activities按照它們被開啟的順序,被安放在一個堆疊裡(back stack)。

  一個activity甚至可以開啟其他應用的activity。

  比如你的應用需要傳送一個電子郵件,你可以定義一個intent來執行傳送動作,intent包含一些必要的資料,然後啟動另一個應用中的activity來執行傳送郵件的動作,當郵件傳送完,又回到你的activity。

  Android會將這兩個activity放在同一個task中來保持一致的使用者體驗。

Activity壓棧

  當前的activity啟動一個新的activity時,新的activity會被壓在back stack的棧頂並且獲得焦點。

  前一個activity仍然在棧中,但是stopped。

  當一個activity停止時,系統會保持它的使用者互動狀態。

  當用戶按下Back鍵,當前activity會出棧(這個activity會被銷燬),前一個activity會被恢復,並且它的UI狀態也會被恢復。

  當棧中的activities依次彈出,棧空了之後,task就不存在了。

Multitasking:Task在後臺

  Task也只是一個有凝聚力的單元,當用戶開啟一個新的task,或者Home鍵回到桌面時,task將會變為在後臺執行。

  當Task在後臺時,其中所有的activity都是停止的,back stack保持不變,這個task只是失去了焦點。

  Task可以回到前臺狀態,這樣使用者就可以回到他們離開的現場,即最頂端的activity會resume。

  後臺中可以保持多個task,但是系統可能會kill後臺的activity用來恢復記憶體,這樣就會導致activity的狀態丟失。

儲存Activity狀態

  當activity停止時(stopped),系統的預設行為是儲存它的狀態。

  然而,你可以,並且應該使用回撥方法主動保留你的狀態,以防activity被系統kill而需要重建。

  當系統為了恢復記憶體而kill掉activity時,activity的狀態資訊會丟失。

  但是系統仍然知道這個activity在back stack中的位置,當這個activity返回到棧頂時,系統會重建(recreate)它,而不是像之前一樣恢復它(resume)。

  所以為了不丟失使用者的工作,你需要實現 onSaveInstanceState() 方法來主動地儲存資料。

管理Task

  Android系統是這樣管理task和back stack的:將activity按照啟動的順序壓入堆疊中,如果一個activity被啟動多次,會建立它的多個例項,然後將新的例項壓入棧中。

  如果你想介入並更改這種預設的行為也可以。

  比如你可能想在你的某一個activity啟動時新開啟一個task(而不是放在當前task中);

  又或者,當你啟動一個activity時,你希望把它的現有例項提到前面來(而不是在棧頂建立一個新的例項);

  或者,你希望在使用者離開你的task時清除除了根activity之外的所有activity。

  要做這些事,你可以通過manifest中 <activity>元素的屬性,還可以通過設定 startActivity()中傳遞的intent的flag來完成。

你可以使用的 <activity> 的屬性:

以及主要的intent的flag:

定義啟動模式

  啟動模式允許你定義一個新的activity例項是如何和當前task關聯的。

  你可以通過兩種方式來定義啟動模式:在manifest中定義或者通過用intent的flag。

  這裡有兩點需要注意:

  1.有些啟動模式只能在manifest中定義,也有一些只能通過intent的flag定義。

  2.當一個activity A啟動一個activity B時,如果B在它的manifest中定義了啟動模式,但是A通過intent要求它用另一種啟動模式,以A的要求為主。

使用manifest file定義啟動模式

  可以在manifest檔案中 <activity>標籤下使用 launchMode 屬性定義activity和task關聯的方式,它規定了activity如何啟動並進入一個task。

  注意,在manifest中定義的啟動模式可以被啟動activity的intent中的flag標明的模式覆蓋。

  有下面幾種屬性值:

"standard" (the default mode)

  預設模式。在當前task中,activity的新例項被建立,並且傳遞intent給它。一個activity可以被例項化多次,每個例項可以屬於不同的task,一個task也可以有多個它的例項。

"singleTop"

  如果當前task的頂部已經有一個這個activity的例項,系統就通過 onNewIntent() 方法向這個例項傳遞intent,而不是重新建立activity的例項。

  一個activity可以被例項化多次,並且例項可以屬於不同的task,一個task也可以有多個它的例項(頂部的activity不是這個activity的例項時,就會重新例項化)。

"singleTask"

  系統將會重新建立一個task並且例項化activity,將其放在task的根部。

  然而,如果這個activity的例項已經在一個單獨的task中存在,系統將會呼叫 onNewIntent() 方法將新的intent傳遞給這個已經存在的例項,而不是重新建立例項。

  在任一時刻,只能有一個這個activity的例項存在。

"singleInstance"

  和"singleTask"類似,唯一不同的是系統不會在這個activity的例項所在的task中啟動任何其他activity。

  這個activity的例項永遠是這個task中的唯一一個成員,這個activity啟動的任何其他activity都將在另外的task中開啟。

返回處理

  不管activity是在一個新的task啟動還是當前task啟動,返回鍵永遠把使用者帶到之前的那個activity。

  但是有一種特殊情況:如果你啟動一個啟動模式為singleTask的activity,如果這個activity在一個後臺task存在例項,那麼這整個task將會被放到前臺,這時候,back stack就會包含這個task中所有的activities,並且它們是放在棧頂。

  如下圖:

使用Intent的flag標明啟動模式

  通過設定傳遞給 startActivity()的intent的flag,可以修改要啟動的activity和它的task的關聯模式。

  可以使用的flags有:

FLAG_ACTIVITY_NEW_TASK

  和之前討論過的"singleTask"相同,在新的task中啟動activity,如果一個你需要的activity的task已經存在,則將它推向前臺,恢復其上一個狀態,它通過onNewIntent()收到這個新的intent。

FLAG_ACTIVITY_SINGLE_TOP

  和"singleTop"行為相同,如果被啟動的activity是當前頂部的activity,則已經存在的例項收到 onNewIntent(),而不是新建例項。

FLAG_ACTIVITY_CLEAR_TOP

  如果被啟動的activity已經在當前task執行,不建立它的新例項,而是銷燬在它之上的其他所有activities,然後通過 onNewIntent()傳遞一個新的intent給這個恢復了的activity。

  這個行為在 launchMode 中沒有對應的屬性值。

  注意,如果activity的啟動模式是"standard",它自己也將被移除,然後一個新的例項將被啟動。

  這是因為當啟動模式是"standard"時,為了接收新的intent必須建立新的例項。

處理affinities

  Affinity指示了activity更傾向於屬於哪個task。

  預設情況下,同一個應用的activities傾向於在同一個task中。你可以通過<activity>標籤中的 taskAffinity來修改這種行為。

  詳細內容請檢視:API Guides: Tasks and Back Stack

  http://developer.android.com/guide/components/tasks-and-back-stack.html

清理Back stack

  如果使用者離開一個task很久,系統就會清理這個task中的所有activities,除了根activity。當用戶返回到這個task,只有根activity會被恢復。

  

  有一些activity的屬性,你可以用來改變這一行為:

alwaysRetainTaskState

  如果這個屬性在task的根activity中被設定為true,那麼上面描述的預設行為不會發生,即便過了很長時間,task仍將會保持所有的activities。

clearTaskOnLaunch

  如果這個屬性在task的根activity中被設定為true,每次使用者離開這個task,整個task都會被清到只剩根activity。

  這樣使用者永遠只能返回到它最初的狀態,即便離開的時間很短。

finishOnTaskLaunch

  這個屬性和上一個很像,但是它作用於單個activity,而不是整個task。

  它可以引起任何activity離開,包括根activity。

  當它被設定為true時,這個activity只在當前會話中屬於這個task,如果使用者離開再返回,它不會再出現。

開啟一個task

  你可以通過給activity一個intent filter(action是"android.intent.action.MAIN",category是"android.intent.category.LAUNCHER"),讓這個activity是一個task的進入點。

  如下:

<activity ... >
<intent-filter ... >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
...
</activity>

  一個這樣的intent filter會使得這個activity的icon和label顯示在程式啟動處,提供了一種方法,使得使用者可以啟動這個activity,當它啟動後,使用者也可以通過它來返回到這個task。

  第二個能力是很重要的:使用者必須能夠離開一個task,然後通過activity launcher返回到它。

  因為這個原因,兩個讓activity永遠例項化一個task的啟動模式:"singleTask" 和"singleInstance",應該僅在activity有一個  ACTION_MAIN 和CATEGORY_LAUNCHER filter的時候用它們。

參考資料

  API Guides: Tasks and Back Stack

  http://developer.android.com/guide/components/tasks-and-back-stack.html

  <activity>標籤:

  http://developer.android.com/guide/topics/manifest/activity-element.html

  關於啟動模式,還可以參見博文:

  http://www.cnblogs.com/fanchangfa/archive/2012/08/25/2657012.html