android中activity啓動模式

在Android平臺上可以將task簡單的理解爲幽多個Activity共同協作完成某項應用,而不管Activity具體屬於哪個Application,通過下圖可以更清晰的理解Application、task、Activity三者之間的關係
 

 

 

Task和Activity相關

這段時間在做一個項目,發現對Task和Activity掌握的還是不牢固。把相關知識整理在這裏,方便查閱,有幾個Flag沒看明白啥意思,也沒測試出來效果如何。。。

 

 android:allowTaskReparenting
    用來標記Activity能否從啓動的Task移動到有着affinity的Task(當這個Task進入到前臺時)——“true”,表示能移動,“false”,表示它必須呆在啓動時呆在的那個Task裏。
    如果這個特性沒有被設定,設定到<application>元素上的allowTaskReparenting特性的值會應用到Activity上。默認值爲“false”。
    一般來說,當Activity啓動後,它就與啓動它的Task關聯,並且在那裏耗盡它的整個生命週期。噹噹前的Task不再顯示時,你可以使用這個特性來 強制Activity移動到有着affinity的Task中。典型用法是:把一個應用程序的Activity移到另一個應用程序的主Task中。
    例如,如果e-mail中包含一個web頁的鏈接,點擊它就會啓動一個Activity來顯示這個頁面。這個Activity是由Browser應用程序 定義的,但是,現在它作爲e-mail Task的一部分。如果它重新宿主到Browser Task裏,當Browser下一次進入到前臺時,它就能被看見,並且,當e-mail Task再次進入前臺時,就看不到它了。
    Actvity的affinity是由taskAffinity特性定義的。Task的affinity是通過讀取根Activity的affinity 決定。因此,根據定義,根Activity總是位於相同affinity的Task裏。由於啓動模式爲“singleTask”和 “singleInstance”的Activity只能位於Task的底部,因此,重新宿主只能限於“standard”和“singleTop”模 式。

android:alwaysRetainTaskState
    用來標記Activity所在的Task的狀態是否總是由系統來保持——“true”,表示總是;“false”,表示在某種情形下允許系統恢復Task 到它的初始化狀態。默認值是“false”。這個特性只針對Task的根Activity有意義;對其它Activity來說,忽略之。
    一般來說,特定的情形如當用戶從主畫面重新選擇這個Task時,系統會對這個Task進行清理(從stack中刪除位於根Activity之上的所有Activivity)。典型的情況,當用戶有一段時間沒有訪問這個Task時也會這麼做,例如30分鐘。
    然而,當這個特性設爲“true”時,用戶總是能回到這個Task的最新狀態,無論他們是如何啓動的。這非常有用,例如,像Browser應用程序,這裏有很多的狀態(例如多個打開的Tab),用戶不想丟失這些狀態。

android:clearTaskOnLaunch
    用來標記是否從Task中清除所有的Activity,除了根Activity外(每當從主畫面重新啓動時)——“true”,表示總是清除至它的根 Activity,“false”表示不。默認值是“false”。這個特性只對啓動一個新的Task的Activity(根Activity)有意義; 對Task中其它的Activity忽略。
    當這個值爲“true”,每次用戶重新啓動這個Task時,都會進入到它的根Activity中,不管這個Task最後在做些什麼,也不管用戶是使用 BACK還是HOME離開的。當這個值爲“false”時,可能會在一些情形下(參考alwaysRetainTaskState特性)清除Task的 Activity,但不總是。
    假設,某人從主畫面啓動了Activity P,並從那裏遷移至Activity Q。接下來用戶按下HOME,然後返回Activity P。一般,用戶可能見到的是Activity Q,因爲它是P的Task中最後工作的內容。然而,如果P設定這個特性爲“true”,當用戶按下HOME並使這個Task再次進入前臺時,其上的所有的 Activity(在這裏是Q)都將被清除。因此,當返回到這個Task時,用戶只能看到P。
    如果這個特性和allowTaskReparenting都設定爲“true”,那些能重新宿主的Activity會移動到共享affinity的Task中;剩下的Activity都將被拋棄,如上所述。

android:finishOnTaskLaunch
    用來標記當用戶再次啓動它的Task(在主畫面選擇這個Task)時已經存在的Activity實例是否要關閉(結束)——“true”,表示應該關閉,“false”表示不關閉。默認值是“false”。
    如果這個特性和allowTaskReparenting都設定爲“true”,這個特性勝出。Activity的affinity忽略。這個Activity不會重新宿主,但是會銷燬。

android:launchMode
    用於指示Activity如何啓動。這裏有四種模式,與Intent對象中的Activity Flags(FLAG_ACTIVITY_*變量)共同作用,來決定Activity如何啓動來處理Intent。它們是:

    "standard"
    "singleTop"
    "singleTask"
    "singleInstance"

    默認模式是“standard”。
    
    這些模式可以分成兩大組別,“standard”和“singleTop”一組,“singleTask”和“singleInstance”一組。具有 “standard”和“singleTop”啓動模式的Activity可以實例化很多次。這些實例可以屬於任何Task並且可以位於Activity stack的任何位置。典型的情況是,它們會進入調用startActivity()的Task(除非Intent對象包含 FLAG_ACTIVITY_NEW_TASK標誌,在這種情況下會選擇一個不同的Task——參考taskAffinity特性)。
    相反的,“singleTask”和“singleInstance”只能啓動一個Task。它們總是位於Activity stack的底部。甚至,設備一次只能擁有一個Activity的實例——只有一個這樣的Task。
    “standard”和“singleTop”模式只在一種情況下有差別:每次有一個新的啓動“standard”Activity的Intent,就會 創建一個新的實例來響應這個Intent。每個實例處理一個Intent。相似的,一個“singleTop”的Activity實例也有可能被創建來處 理新的Intent。然而,如果目標Task已經有一個存在的實例並且位於stack的頂部,那麼,這個實例就會接收到這個新的Intent(調用 onNewIntent());不會創建新的實例。在其他情況下——例如,如果存在的“singleTop”的Activity實例在目標Task中,但 不是在stack的頂部,或者它在一個stack的頂部,但不是在目標Task中——新的實例都會被創建並壓入stack中。
    “singleTask”和“singleInstance”模式也只在一種情況下有差別:“singleTask”Activity允許其它 Activity成爲它的Task的部分。它位於Activity stack的底部,其它Activity(必須是“standard”和“singleTop”Activity)可以啓動加入到相同的Task中。 “singleInstance”Activity,換句話說,不允許其它Activity成爲它的Task的部分。它是Task中的唯一 Activity。如果它啓動其它的Activity,這個Activity會被放置到另一個task中——好像Intent中包含了 FLAG_ACTIVITY_NEW_TASK標誌。

android:noHistory
    用於標記當用戶從Activity上離開並且它在屏幕上不再可見時Activity是否從Activity stack中清除並結束(調用finish()方法)——“true”,表示它應該關閉,“false”,表示不需要。默認值是“false”。
    “true”值意味着Activity不會留下歷史痕跡。因爲它不會在Activity stack的Task中保留,因此,用戶不能返回它。

android:taskAffinity
   Activity爲Task擁有的一個affinity。擁有相同的affinity的Activity理論上屬於相同的Task(在用戶的角度是相同的“應用程序”)。Task的affinity是由它的根Activity決定的。 
   affinity決定兩件事情——Activity重新宿主的Task(參考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK標誌啓動的Activity宿主的Task。
    默認情況,一個應用程序中的所有Activity都擁有相同的affinity。捏可以設定這個特性來重組它們,甚至可以把不同應用程序中定義的Activity放置到相同的Task中。爲了明確Activity不宿主特定的Task,設定該特性爲空的字符串。
    如果這個特性沒有設置,Activity將從應用程序的設定那裏繼承下來(參考<application>元素的taskAffinity特 性)。應用程序默認的affinity的名字是<manifest>元素中設定的package名。

FLAG_ACTIVITY_BROUGHT_TO_FRONT 
    這個標誌一般不是由程序代碼設置的,如在launchMode中設置singleTask模式時系統幫你設定。

FLAG_ACTIVITY_CLEAR_TOP
    如果設置,並且這個Activity已經在當前的Task中運行,因此,不再是重新啓動一個這個Activity的實例,而是在這個Activity上方 的所有Activity都將關閉,然後這個Intent會作爲一個新的Intent投遞到老的Activity(現在位於頂端)中。
    例如,假設一個Task中包含這些Activity:A,B,C,D。如果D調用了startActivity(),並且包含一個指向Activity B的Intent,那麼,C和D都將結束,然後B接收到這個Intent,因此,目前stack的狀況是:A,B。
    上例中正在運行的Activity B既可以在onNewIntent()中接收到這個新的Intent,也可以把自己關閉然後重新啓動來接收這個Intent。如果它的啓動模式聲明爲 “multiple”(默認值),並且你沒有在這個Intent中設置FLAG_ACTIVITY_SINGLE_TOP標誌,那麼它將關閉然後重新創 建;對於其它的啓動模式,或者在這個Intent中設置FLAG_ACTIVITY_SINGLE_TOP標誌,都將把這個Intent投遞到當前這個實 例的onNewIntent()中。
    這個啓動模式還可以與FLAG_ACTIVITY_NEW_TASK結合起來使用:用於啓動一個Task中的根Activity,它會把那個Task中任 何運行的實例帶入前臺,然後清除它直到根Activity。這非常有用,例如,當從Notification Manager處啓動一個Activity。

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
    如果設置,這將在Task的Activity stack中設置一個還原點,當Task恢復時,需要清理Activity。也就是說,下一次Task帶着 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED標記進入前臺時(典型的操作是用戶在主畫面重啓它),這個Activity和它之 上的都將關閉,以至於用戶不能再返回到它們,但是可以回到之前的Activity。
    這在你的程序有分割點的時候很有用。例如,一個e-mail應用程序可能有一個操作是查看一個附件,需要啓動圖片瀏覽Activity來顯示。這個 Activity應該作爲e-mail應用程序Task的一部分,因爲這是用戶在這個Task中觸發的操作。然而,當用戶離開這個Task,然後從主畫面 選擇e-mail app,我們可能希望回到查看的會話中,但不是查看圖片附件,因爲這讓人困惑。通過在啓動圖片瀏覽時設定這個標誌,瀏覽及其它啓動的Activity在下 次用戶返回到mail程序時都將全部清除。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    如果設置,新的Activity不會在最近啓動的Activity的列表中保存。

FLAG_ACTIVITY_FORWARD_RESULT
    如果設置,並且這個Intent用於從一個存在的Activity啓動一個新的Activity,那麼,這個作爲答覆目標的Activity將會傳到這個 新的Activity中。這種方式下,新的Activity可以調用setResult(int),並且這個結果值將發送給那個作爲答覆目標的 Activity。

FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY 
    這個標誌一般不由應用程序代碼設置,如果這個Activity是從歷史記錄裏啓動的(常按HOME鍵),那麼,系統會幫你設定。

FLAG_ACTIVITY_MULTIPLE_TASK 
    不要使用這個標誌,除非你自己實現了應用程序啓動器。與FLAG_ACTIVITY_NEW_TASK結合起來使用,可以禁用把已存的Task送入前臺的 行爲。當設置時,新的Task總是會啓動來處理Intent,而不管這是是否已經有一個Task可以處理相同的事情。
    由於默認的系統不包含圖形Task管理功能,因此,你不應該使用這個標誌,除非你提供給用戶一種方式可以返回到已經啓動的Task。
    如果FLAG_ACTIVITY_NEW_TASK標誌沒有設置,這個標誌被忽略。

FLAG_ACTIVITY_NEW_TASK 
    如果設置,這個Activity會成爲歷史stack中一個新Task的開始。一個Task(從啓動它的Activity到下一個Task中的 Activity)定義了用戶可以遷移的Activity原子組。Task可以移動到前臺和後臺;在某個特定Task中的所有Activity總是保持相 同的次序。
    這個標誌一般用於呈現“啓動”類型的行爲:它們提供用戶一系列可以單獨完成的事情,與啓動它們的Activity完全無關。
    使用這個標誌,如果正在啓動的Activity的Task已經在運行的話,那麼,新的Activity將不會啓動;代替的,當前Task會簡單的移入前臺。參考FLAG_ACTIVITY_MULTIPLE_TASK標誌,可以禁用這一行爲。
    這個標誌不能用於調用方對已經啓動的Activity請求結果。

FLAG_ACTIVITY_NO_ANIMATION 
    如果在Intent中設置,並傳遞給Context.startActivity()的話,這個標誌將阻止系統進入下一個Activity時應用 Acitivity遷移動畫。這並不意味着動畫將永不運行——如果另一個Activity在啓動顯示之前,沒有指定這個標誌,那麼,動畫將被應用。這個標 志可以很好的用於執行一連串的操作,而動畫被看作是更高一級的事件的驅動。

FLAG_ACTIVITY_NO_HISTORY 
    如果設置,新的Activity將不再歷史stack中保留。用戶一離開它,這個Activity就關閉了。這也可以通過設置noHistory特性。

FLAG_ACTIVITY_NO_USER_ACTION 
    如果設置,作爲新啓動的Activity進入前臺時,這個標誌將在Activity暫停之前阻止從最前方的Activity回調的onUserLeaveHint()。
    典型的,一個Activity可以依賴這個回調指明顯式的用戶動作引起的Activity移出後臺。這個回調在Activity的生命週期中標記一個合適的點,並關閉一些Notification。
    如果一個Activity通過非用戶驅動的事件,如來電或鬧鐘,啓動的,這個標誌也應該傳遞給Context.startActivity,保證暫停的Activity不認爲用戶已經知曉其Notification。

FLAG_ACTIVITY_PREVIOUS_IS_TOP 
    If set and this intent is being used to launch a new activity from an existing one, the current activity will not be counted as the top activity for deciding whether the new intent should be delivered to the top instead of starting a new one. The previous activity will be used as the top, with the assumption being that the current activity will finish itself immediately. 

FLAG_ACTIVITY_REORDER_TO_FRONT
    如果在Intent中設置,並傳遞給Context.startActivity(),這個標誌將引發已經運行的Activity移動到歷史stack的頂端。
    例如,假設一個Task由四個Activity組成:A,B,C,D。如果D調用startActivity()來啓動Activity B,那麼,B會移動到歷史stack的頂端,現在的次序變成A,C,D,B。如果FLAG_ACTIVITY_CLEAR_TOP標誌也設置的話,那麼這 個標誌將被忽略。

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

If set, and this activity is either being started in a new task or bringing to the top an existing task, then it will be launched as the front door of the task. This will result in the application of any affinities needed to have that task in the proper state (either moving activities to or from it), or simply resetting that task to its initial state if needed. 

FLAG_ACTIVITY_SINGLE_TOP
    如果設置,當這個Activity位於歷史stack的頂端運行時,不再啓動一個新的。 

 

 

ActivityTask

 

之前提到的,一個Activity可以啓動另一個,即便是定義在不同應用程序中的Activity。例如,假設你想讓用戶顯示一些地方的街景。而這裏已經有一個Activity可以做到這一點,因此,你的Activity所需要做的只是在Intent對象中添加必要的信息,並傳遞給startActivity()。地圖瀏覽將會顯示你的地圖。當用戶按下BACK鍵,你的Activity會再次出現在屏幕上。

 

對於用戶來說,看起來好像是地圖瀏覽與你的Activity一樣,屬於相同的應用程序,即便是它定義在其它的應用程序裏,並運行在那個應用程序的進程裏。Android通過將這兩個Activity保存在同一個Task裏來體現這一用戶體驗。簡單來說,一個Task就是用戶體驗上的一個“應用”。它將相關的Activity組合在一起,以stack的方式管理。stack中根Activity啓動Task——典型的,它就是用戶在應用程序啓動欄中選擇的Activity。位於stack頂端的Activity是當前正在運行的——能夠聚焦用戶的動作。當一個Activity啓動另一個,新的Activity進入stack;它成爲正在運行的Activity。之前的Activity仍保留在stack中。當用戶按下BACK鍵,當前的Activitystack中退出,之前的那個成爲正在運行的Activity

 

stack包含對象,因此,如果一個Task中有多個同一個Activity的實例時——多個地圖瀏覽,例如——stack爲每個實例擁有一個獨立的入口。位於stack中的Activity不會重新調整,只是進入和退出。

 

一個Task就是一組Activity,不是一個類或者在manifest中定義的一個元素。因此,沒有辦法爲Task設置獨立於它的Activity的屬性值。Task的值作爲整體在根Activity中設置。例如,下一個章節會討論Task的“affinity”;那個值就是從Task中的根Activity中讀取的。

 

Task中的所有Activity作爲一個單元一起移動。整個Task(整個Activity stack)可以進入前臺或者退到後臺。例如,假設當前Task中的stack中有4Activity——3個位於當前Activity下方。用戶按下HOME鍵,進入到應用程序啓動欄,然後選擇一個新的應用程序(實際上,一個新的Task)。當前Task退到後臺,並且新Task中的根Activity會顯示出來。然後,經過一段時間後,用戶回到Home畫面,然後再次選擇前一個應用程序(前一個Task)。那個擁有4ActivityTask會進入前臺。當用戶按下BACK鍵,屏幕不會顯示用戶剛剛離開的Activity(前一個Task的根Activity)。而是,這個stack中的頂端Activity移除,相同Task中的前一個Activity會顯示出來。

 

剛纔描述的行爲是ActivityTask的默認行爲。但有方法來完全改變它。Task之間的關聯,和一個Task中的一個Activity行爲,受啓動ActivityIntent對象中設置的Flagmanifest文件中Activity<activity>元素的特性值交互控制。調用者和響應者都有權決定如何發生。

 

核心的Intent Flag有:

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

FLAG_ACTIVITY_SINGLE_TOP

 

核心的<activity>特性有:

taskAffinity

launchMode

allowTaskReparenting

clearTaskOnLaunch

alwaysRetainTaskState

finishOnTaskLaunch

 

接下來的章節將描述一些Flag和特性的用法,如何相互影響,以及在使用時的建議。

 

Affinity和新Task

默認情況下,一個應用程序中的所有Activity都有affinity——也就是說,屬於同一個Task中所有Activity有一個設定。然而,每個Activity都可以在<activity>元素的taskAffinity特性上設置單獨的值。定義在不同應用程序中的Activity可以共享同一個affinity,或者定義在同一個應用程序中的Activity設置不同的affinityAffinity在兩種環境下工作:Intent對象包含FLAG_ACTIVITY_NEW_TASK標誌,和ActivityallowTaskReparenting特性設置爲“true”。

FLAG_ACTIVITY_NEW_TASK:

之前描述的,一個Activity一般通過調用startActivity()啓動並加入到Task中。它同調用者一樣,進入同一個Task。然而,如果傳遞給startActivity()Intent對象中包含FLAG_ACTIVITY_NEW_TASK時,系統會搜索一個新的Task來容納新的Activity。通常,如標誌的名字所示,是一個新的Task。然而,並不是必須是。如果已經存在一個Task與新Activityaffinity相同,這個Activity就會加入到那個Task中。如果不是,啓動一個新的Task

allowTaskReparenting

如果一個ActivityallowTaskReparenting特性設置爲“true”,它就能從啓動的Task中移到有着相同affinityTask(這個Task進入到前臺的時候)。例如,在一個旅遊的程序中定義了一個可以報告選擇城市的天氣情況的Activity。它和同一個應用程序的其它Activity一樣,有着相同的Affinity(默認的Affinity),並且它允許重新宿主。你的Activity中的一個啓動了天氣預報,因此,它初始化到和你Activity相同的Task中。然而,當旅遊應用程序下一次進入到前臺時,天氣預報那個Activity將會重新編排並在那個Task中顯示。

 

如果從用戶的角度出發,一個.apk文件包含多個“應用”的話,你可能希望爲關聯的Activity設置不同的affinity

 

Launch Mode

 

這裏4種不同的啓動模式可以設置到<activity>元素的launchMode特性上:

standard(默認模式)

singleTop

singleTask

singleInstance

 

這些模式有以下四點區別:

哪個Task將容納響應IntentActivity。對於“standard”和“singleTop”來說,是產生Intent的那個Task(並調用startActivity())——除非Intent對象包含FLAG_ACTIVITY_NEW_TASK。在那種情況下,不同的Task將被選擇,如“Affinity和新Task”中描述的那樣。對比而言,“singleTask”和“singleInstance”指示Activity總是一個Task的根。它們定義一個Task;它們不會加入到另一個Task中。

是否有多個Activity的實例。“standard”和“singleTop”可以實例化多次。它們可以屬於多個Task,一個特定的Task可以有相同Activity的多個實例。對比而言,“singleTask”和“singleInstance”只能有一個實例。因爲這些Activity只能位於Task的底部,這一限制意味着在設備的某個時間,不會出現這樣Task的多個實例。

是否可以在同一個Task中擁有其它的Activity。“singleInstanceActivity保持單身,在它的Task中它是僅有的Activity。如果它啓動另一個Activity,那個Activity將會放入到不同的Task中,而不管它的啓動模式——好像FLAG_ACTIVITY_NEW_TASKIntent中一樣。對於其它方面,,“singleInstance”等同於“singleTask”。其它三個模式允許多個Activity加入到這個Task中。“singleTaskActivity總是位於Task的底部,但它可以啓動其它的Activity並放入到它的Task中。“standard”和“singleTop”的Activity可以出現在stack的任何地方。

是否一個新的實例啓動來處理新的Intent。對於默認的“standard”來說,都是創建一個新的實例來響應新的Intent。每個實例處理一個Intent。對於“singleTop”來說,如果它位於目標Task的頂端,那麼,已經存在的實例就可以重複使用來處理這個新的Intent。如果它不在頂端,那麼它就不能重複使用。替代的,新的實例將創建來響應新的Intent,並進入到stack中。

例如,假設一TaskActivity stack中包含根Activity A和其它Activity BCD,並且D位於頂端,因此,stackA-B-C-D。有一個Intent來了,它要啓動D類型的Activity。如果D有默認的“standard”啓動模式,那麼,一個新的實例將被啓動並且stack變成A-B-C-D-D。然而,如果D的啓動模式“singleTop”,已經存在的實例將去處理新來的Intent(因爲它正好處在stack的頂端),並且stack依舊是A-B-C-D

換句話說,如果來臨的Intent是衝着B類型的,那麼,B類型的實例將被創建啓動而不管B的模式是“standard”或“singleTop”(因爲B不處在stack的頂端),因此,stack將會是A-B-C-D-B

之前提到的,設備上不會出現超過一個實例的“singleTask”或“singleInstanceActivity,因此,那個實例都將去處理所有新來的Intent。“singleInstanceActivity總是位於stack的頂端(因爲它是task中唯一的Activity),因此,它總是處於能處理Intent的位置。然而,“singleTaskActivity可能有或沒有其它Activity處於它的上方。如果有,它就不處於能處理Intent的位置,那麼,這個Intent將被丟棄。(即使Intent被丟棄了,它的到來會引發那個Task進入到前臺,在那裏,它會繼續保留。)

 

當一個存在的Activity請求去處理一個新的Intent時,Intent對象將傳到該ActivityonNewIntent()的方法中。(原來啓動ActivityIntent對象可以通過調用getIntent()得到。)

 

注意:當一個新的實例創建來處理新的Intent時,用戶可以按下BACK鍵返回到之前的狀態(前一個Activity)。但一個存在的實例來處理新的Intent時,用戶不能按下BACK鍵返回到新Intent到來之前的狀態。

 

清除stack

如果用戶離開Task很長一段時間,系統會清除Task中的所有Activity,除根Activity外。當用戶再次返回到這個Task時,和用戶離開時一樣,僅僅只是初始化Activity呈現。這樣做的意圖是,經過一些時間後,用戶可能已經忘記之前正在做的事情,並且打算回到Task開始些新的時期。

 

這是默認情況。這裏有一些Activity特性可以用於控制這一行爲並且修改它:

alwaysRetainTaskState

如果Task的根Activity的這個特性設置爲“true”時,上面描述的默認行爲不會發生。Task保留所有的Activity,即便是經過很長一段時間。

clearTaskOnLaunch

如果Task的根Activity的這個特性設置爲“true”時,當用戶離開Task並返回時,stack會清除直到根Activity。換句話說,它是alwaysRetainTaskState的另一個極端。用戶總是回到Task的初始化狀態,即便是一個短暫的離開。

finishOnTaskLaunch

這個特性和clearTaskOnLaunch相似,但它針對單個Activity,不是整個Task。它能使任何Activity消失,包括根Activity。當它設置爲“true”時,這個Activity僅在當前會話期間保持爲Task的部分。如果用戶離開並再次返回到這個Task,它就不再顯示了。

 

這裏還有其它的方式可以強制Activitystack中移除。如果Intent對象中包含FLAG_ACTIVITY_CLEAR_TOP標誌,並且目標Task中已經有一個這個類型Activity的實例,而且這個實例應該處理這個Intent,那麼,位於其上的Activity都將移除,這樣,這個Activity就能在stack的頂端並響應這個Intent。如果這個Activity的啓動模式設定爲“standard”,它也會從stack中清除,然後新的實例啓動來響應這個Intent。這是因爲當啓動模式設定爲“standard“時,總是會創建一個新的實例來響應新的Intent

 

FLAG_ACTIVITY_CLEAR_TOP經常與FLAG_ACTIVITY_NEW_TASK結合起來使用。當一起使用時,這些標誌可以定位其它Task中已經存在的Activity,並且把它置於可以響應Intent的位置。

 

啓動Task

如果一個ActivityIntent Filteraction爲“android.intent.action.MAIN”、category爲“android.intent.category.LAUNCHER”時,它就可以作爲一個Task的入口點。有這種類型的Filter會在導致這個Activity在應用程序啓動欄顯示一個圖標和標籤,給用戶提供一個方式可以啓動這個Task和在任何時候可以再次回到這個Task

 

第二個能力很重要:用戶一定可以離開一個Task,然後可以再次回到它。基於這個原因,兩個啓動模式,“singleTask”和“singleInstance”應該只在有MAINLAUNCHERActivity上使用。例如,假設這個Filter沒有的話:一個Intent啓動了一個“singleTaskActivity,初始化一個新的Task,然後用戶花費了一些時間在它上面。然後,用戶按下HOME鍵。現在,這個Task處於後臺並且被HOME畫面遮蓋。由於它不能在應用程序啓動欄顯示,用戶就沒有辦法可以返回它。

 

在面對FLAG_ACTIVITY_NEW_TASK時,也有相似的困難。如果這個標誌導致一個Activity啓動了一個新的Task,並且用戶按下HOME鍵離開它,這裏必須有方法可以再次回到它。一些機能(如Notification Manager)總是在外部的Task中啓動Activity,而不是作爲自己的一部分,因此,它總是把FLAG_ACTIVITY_NEW_TASK標誌放入Intent,然後傳遞給startActivity()。如果你的Activity可能會被外部的機能(可能使用這個標誌)調用,注意用戶可以額外的方式可以返回到啓動的Task

 

如果你不想用戶回到某個Activity,可以把<activity>元素的finishOnTaskLaunch設置爲“true”。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章