<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Calvin's Tech Space

    成于堅(jiān)忍,毀于浮躁

       :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
    Task和Activity相關(guān)

    這段時(shí)間在做一個(gè)項(xiàng)目,發(fā)現(xiàn)對(duì)Task和Activity掌握的還是不牢固。把相關(guān)知識(shí)整理在這里,方便查閱,有幾個(gè)Flag沒(méi)看明白啥意思,也沒(méi)測(cè)試出來(lái)效果如何。。。

    android:allowTaskReparenting
    用來(lái)標(biāo)記Activity能否從啟動(dòng)的Task移動(dòng)到有著affinity的Task(當(dāng)這個(gè)Task進(jìn)入到前臺(tái)時(shí))——“true”,表示能移動(dòng),“false”,表示它必須呆在啟動(dòng)時(shí)呆在的那個(gè)Task里。
    如果這個(gè)特性沒(méi)有被設(shè)定,設(shè)定到元素上的allowTaskReparenting特性的值會(huì)應(yīng)用到Activity上。默認(rèn)值為“false”。
    一般來(lái)說(shuō),當(dāng)Activity啟動(dòng)后,它就與啟動(dòng)它的Task關(guān)聯(lián),并且在那里耗盡它的整個(gè)生命周期。當(dāng)當(dāng)前的Task不再顯示時(shí),你可以使用這個(gè)特性來(lái)強(qiáng)制Activity移動(dòng)到有著affinity的Task中。典型用法是:把一個(gè)應(yīng)用程序的Activity移到另一個(gè)應(yīng)用程序的主Task中。
    例如,如果e-mail中包含一個(gè)web頁(yè)的鏈接,點(diǎn)擊它就會(huì)啟動(dòng)一個(gè)Activity來(lái)顯示這個(gè)頁(yè)面。這個(gè)Activity是由Browser應(yīng)用程序定義的,但是,現(xiàn)在它作為e-mail Task的一部分。如果它重新宿主到Browser Task里,當(dāng)Browser下一次進(jìn)入到前臺(tái)時(shí),它就能被看見(jiàn),并且,當(dāng)e-mail Task再次進(jìn)入前臺(tái)時(shí),就看不到它了。
    Actvity的affinity是由taskAffinity特性定義的。Task的affinity是通過(guò)讀取根Activity的affinity決定。因此,根據(jù)定義,根Activity總是位于相同affinity的Task里。由于啟動(dòng)模式為“singleTask”和“singleInstance”的Activity只能位于Task的底部,因此,重新宿主只能限于“standard”和“singleTop”模式。

    android:alwaysRetainTaskState
    用來(lái)標(biāo)記Activity所在的Task的狀態(tài)是否總是由系統(tǒng)來(lái)保持——“true”,表示總是;“false”,表示在某種情形下允許系統(tǒng)恢復(fù)Task到它的初始化狀態(tài)。默認(rèn)值是“false”。這個(gè)特性只針對(duì)Task的根Activity有意義;對(duì)其它Activity來(lái)說(shuō),忽略之。
    一般來(lái)說(shuō),特定的情形如當(dāng)用戶從主畫面重新選擇這個(gè)Task時(shí),系統(tǒng)會(huì)對(duì)這個(gè)Task進(jìn)行清理(從stack中刪除位于根Activity之上的所有Activivity)。典型的情況,當(dāng)用戶有一段時(shí)間沒(méi)有訪問(wèn)這個(gè)Task時(shí)也會(huì)這么做,例如30分鐘。
    然而,當(dāng)這個(gè)特性設(shè)為“true”時(shí),用戶總是能回到這個(gè)Task的最新?tīng)顟B(tài),無(wú)論他們是如何啟動(dòng)的。這非常有用,例如,像Browser應(yīng)用程序,這里有很多的狀態(tài)(例如多個(gè)打開(kāi)的Tab),用戶不想丟失這些狀態(tài)。

    android:clearTaskOnLaunch
    用來(lái)標(biāo)記是否從Task中清除所有的Activity,除了根Activity外(每當(dāng)從主畫面重新啟動(dòng)時(shí))——“true”,表示總是清除至它的根Activity,“false”表示不。默認(rèn)值是“false”。這個(gè)特性只對(duì)啟動(dòng)一個(gè)新的Task的Activity(根Activity)有意義;對(duì)Task中其它的Activity忽略。
    當(dāng)這個(gè)值為“true”,每次用戶重新啟動(dòng)這個(gè)Task時(shí),都會(huì)進(jìn)入到它的根Activity中,不管這個(gè)Task最后在做些什么,也不管用戶是使用BACK還是HOME離開(kāi)的。當(dāng)這個(gè)值為“false”時(shí),可能會(huì)在一些情形下(參考alwaysRetainTaskState特性)清除Task的Activity,但不總是。
    假設(shè),某人從主畫面啟動(dòng)了Activity P,并從那里遷移至Activity Q。接下來(lái)用戶按下HOME,然后返回Activity P。一般,用戶可能見(jiàn)到的是Activity Q,因?yàn)樗荘的Task中最后工作的內(nèi)容。然而,如果P設(shè)定這個(gè)特性為“true”,當(dāng)用戶按下HOME并使這個(gè)Task再次進(jìn)入前臺(tái)時(shí),其上的所有的Activity(在這里是Q)都將被清除。因此,當(dāng)返回到這個(gè)Task時(shí),用戶只能看到P。
    如果這個(gè)特性和allowTaskReparenting都設(shè)定為“true”,那些能重新宿主的Activity會(huì)移動(dòng)到共享affinity的Task中;剩下的Activity都將被拋棄,如上所述。

    android:finishOnTaskLaunch
    用來(lái)標(biāo)記當(dāng)用戶再次啟動(dòng)它的Task(在主畫面選擇這個(gè)Task)時(shí)已經(jīng)存在的Activity實(shí)例是否要關(guān)閉(結(jié)束)——“true”,表示應(yīng)該關(guān)閉,“false”表示不關(guān)閉。默認(rèn)值是“false”。
    如果這個(gè)特性和allowTaskReparenting都設(shè)定為“true”,這個(gè)特性勝出。Activity的affinity忽略。這個(gè)Activity不會(huì)重新宿主,但是會(huì)銷毀。

    android:launchMode
    用于指示Activity如何啟動(dòng)。這里有四種模式,與Intent對(duì)象中的Activity Flags(FLAG_ACTIVITY_*變量)共同作用,來(lái)決定Activity如何啟動(dòng)來(lái)處理Intent。它們是:

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

    默認(rèn)模式是“standard”。

    這些模式可以分成兩大組別,“standard”和“singleTop”一組,“singleTask”和“singleInstance”一組。具有“standard”和“singleTop”啟動(dòng)模式的Activity可以實(shí)例化很多次。這些實(shí)例可以屬于任何Task并且可以位于Activity stack的任何位置。典型的情況是,它們會(huì)進(jìn)入調(diào)用startActivity()的Task(除非Intent對(duì)象包含F(xiàn)LAG_ACTIVITY_NEW_TASK標(biāo)志,在這種情況下會(huì)選擇一個(gè)不同的Task——參考taskAffinity特性)。
    相反的,“singleTask”和“singleInstance”只能啟動(dòng)一個(gè)Task。它們總是位于Activity stack的底部。甚至,設(shè)備一次只能擁有一個(gè)Activity的實(shí)例——只有一個(gè)這樣的Task。
    “standard”和“singleTop”模式只在一種情況下有差別:每次有一個(gè)新的啟動(dòng)“standard”Activity的Intent,就會(huì)創(chuàng)建一個(gè)新的實(shí)例來(lái)響應(yīng)這個(gè)Intent。每個(gè)實(shí)例處理一個(gè)Intent。相似的,一個(gè)“singleTop”的Activity實(shí)例也有可能被創(chuàng)建來(lái)處理新的Intent。然而,如果目標(biāo)Task已經(jīng)有一個(gè)存在的實(shí)例并且位于stack的頂部,那么,這個(gè)實(shí)例就會(huì)接收到這個(gè)新的Intent(調(diào)用onNewIntent());不會(huì)創(chuàng)建新的實(shí)例。在其他情況下——例如,如果存在的“singleTop”的Activity實(shí)例在目標(biāo)Task中,但不是在stack的頂部,或者它在一個(gè)stack的頂部,但不是在目標(biāo)Task中——新的實(shí)例都會(huì)被創(chuàng)建并壓入stack中。
    “singleTask”和“singleInstance”模式也只在一種情況下有差別:“singleTask”Activity允許其它Activity成為它的Task的部分。它位于Activity stack的底部,其它Activity(必須是“standard”和“singleTop”Activity)可以啟動(dòng)加入到相同的Task中。“singleInstance”Activity,換句話說(shuō),不允許其它Activity成為它的Task的部分。它是Task中的唯一Activity。如果它啟動(dòng)其它的Activity,這個(gè)Activity會(huì)被放置到另一個(gè)task中——好像Intent中包含了FLAG_ACTIVITY_NEW_TASK標(biāo)志。

    android:noHistory
    用于標(biāo)記當(dāng)用戶從Activity上離開(kāi)并且它在屏幕上不再可見(jiàn)時(shí)Activity是否從Activity stack中清除并結(jié)束(調(diào)用finish()方法)——“true”,表示它應(yīng)該關(guān)閉,“false”,表示不需要。默認(rèn)值是“false”。
    “true”值意味著Activity不會(huì)留下歷史痕跡。因?yàn)樗粫?huì)在Activity stack的Task中保留,因此,用戶不能返回它。

    android:taskAffinity
    Activity為Task擁有的一個(gè)affinity。擁有相同的affinity的Activity理論上屬于相同的Task(在用戶的角度是相同的“應(yīng)用程序”)。Task的affinity是由它的根Activity決定的。
    affinity決定兩件事情——Activity重新宿主的Task(參考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK標(biāo)志啟動(dòng)的Activity宿主的Task。
    默認(rèn)情況,一個(gè)應(yīng)用程序中的所有Activity都擁有相同的affinity。捏可以設(shè)定這個(gè)特性來(lái)重組它們,甚至可以把不同應(yīng)用程序中定義的Activity放置到相同的Task中。為了明確Activity不宿主特定的Task,設(shè)定該特性為空的字符串。
    如果這個(gè)特性沒(méi)有設(shè)置,Activity將從應(yīng)用程序的設(shè)定那里繼承下來(lái)(參考元素的taskAffinity特性)。應(yīng)用程序默認(rèn)的affinity的名字是元素中設(shè)定的package名。

    FLAG_ACTIVITY_BROUGHT_TO_FRONT
    這個(gè)標(biāo)志一般不是由程序代碼設(shè)置的,如在launchMode中設(shè)置singleTask模式時(shí)系統(tǒng)幫你設(shè)定。

    FLAG_ACTIVITY_CLEAR_TOP
    如果設(shè)置,并且這個(gè)Activity已經(jīng)在當(dāng)前的Task中運(yùn)行,因此,不再是重新啟動(dòng)一個(gè)這個(gè)Activity的實(shí)例,而是在這個(gè)Activity上方的所有Activity都將關(guān)閉,然后這個(gè)Intent會(huì)作為一個(gè)新的Intent投遞到老的Activity(現(xiàn)在位于頂端)中。
    例如,假設(shè)一個(gè)Task中包含這些Activity:A,B,C,D。如果D調(diào)用了startActivity(),并且包含一個(gè)指向Activity B的Intent,那么,C和D都將結(jié)束,然后B接收到這個(gè)Intent,因此,目前stack的狀況是:A,B。
    上例中正在運(yùn)行的Activity B既可以在onNewIntent()中接收到這個(gè)新的Intent,也可以把自己關(guān)閉然后重新啟動(dòng)來(lái)接收這個(gè)Intent。如果它的啟動(dòng)模式聲明為“multiple”(默認(rèn)值),并且你沒(méi)有在這個(gè)Intent中設(shè)置FLAG_ACTIVITY_SINGLE_TOP標(biāo)志,那么它將關(guān)閉然后重新創(chuàng)建;對(duì)于其它的啟動(dòng)模式,或者在這個(gè)Intent中設(shè)置FLAG_ACTIVITY_SINGLE_TOP標(biāo)志,都將把這個(gè)Intent投遞到當(dāng)前這個(gè)實(shí)例的onNewIntent()中。
    這個(gè)啟動(dòng)模式還可以與FLAG_ACTIVITY_NEW_TASK結(jié)合起來(lái)使用:用于啟動(dòng)一個(gè)Task中的根Activity,它會(huì)把那個(gè)Task中任何運(yùn)行的實(shí)例帶入前臺(tái),然后清除它直到根Activity。這非常有用,例如,當(dāng)從Notification Manager處啟動(dòng)一個(gè)Activity。

    FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
    如果設(shè)置,這將在Task的Activity stack中設(shè)置一個(gè)還原點(diǎn),當(dāng)Task恢復(fù)時(shí),需要清理Activity。也就是說(shuō),下一次Task帶著FLAG_ACTIVITY_RESET_TASK_IF_NEEDED標(biāo)記進(jìn)入前臺(tái)時(shí)(典型的操作是用戶在主畫面重啟它),這個(gè)Activity和它之上的都將關(guān)閉,以至于用戶不能再返回到它們,但是可以回到之前的Activity。
    這在你的程序有分割點(diǎn)的時(shí)候很有用。例如,一個(gè)e-mail應(yīng)用程序可能有一個(gè)操作是查看一個(gè)附件,需要啟動(dòng)圖片瀏覽Activity來(lái)顯示。這個(gè)Activity應(yīng)該作為e-mail應(yīng)用程序Task的一部分,因?yàn)檫@是用戶在這個(gè)Task中觸發(fā)的操作。然而,當(dāng)用戶離開(kāi)這個(gè)Task,然后從主畫面選擇e-mail app,我們可能希望回到查看的會(huì)話中,但不是查看圖片附件,因?yàn)檫@讓人困惑。通過(guò)在啟動(dòng)圖片瀏覽時(shí)設(shè)定這個(gè)標(biāo)志,瀏覽及其它啟動(dòng)的Activity在下次用戶返回到mail程序時(shí)都將全部清除。

    FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    如果設(shè)置,新的Activity不會(huì)在最近啟動(dòng)的Activity的列表中保存。

    FLAG_ACTIVITY_FORWARD_RESULT
    如果設(shè)置,并且這個(gè)Intent用于從一個(gè)存在的Activity啟動(dòng)一個(gè)新的Activity,那么,這個(gè)作為答復(fù)目標(biāo)的Activity將會(huì)傳到這個(gè)新的Activity中。這種方式下,新的Activity可以調(diào)用setResult(int),并且這個(gè)結(jié)果值將發(fā)送給那個(gè)作為答復(fù)目標(biāo)的Activity。

    FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
    這個(gè)標(biāo)志一般不由應(yīng)用程序代碼設(shè)置,如果這個(gè)Activity是從歷史記錄里啟動(dòng)的(常按HOME鍵),那么,系統(tǒng)會(huì)幫你設(shè)定。

    FLAG_ACTIVITY_MULTIPLE_TASK
    不要使用這個(gè)標(biāo)志,除非你自己實(shí)現(xiàn)了應(yīng)用程序啟動(dòng)器。與FLAG_ACTIVITY_NEW_TASK結(jié)合起來(lái)使用,可以禁用把已存的Task送入前臺(tái)的行為。當(dāng)設(shè)置時(shí),新的Task總是會(huì)啟動(dòng)來(lái)處理Intent,而不管這是是否已經(jīng)有一個(gè)Task可以處理相同的事情。
    由于默認(rèn)的系統(tǒng)不包含圖形Task管理功能,因此,你不應(yīng)該使用這個(gè)標(biāo)志,除非你提供給用戶一種方式可以返回到已經(jīng)啟動(dòng)的Task。
    如果FLAG_ACTIVITY_NEW_TASK標(biāo)志沒(méi)有設(shè)置,這個(gè)標(biāo)志被忽略。

    FLAG_ACTIVITY_NEW_TASK
    如果設(shè)置,這個(gè)Activity會(huì)成為歷史stack中一個(gè)新Task的開(kāi)始。一個(gè)Task(從啟動(dòng)它的Activity到下一個(gè)Task中的Activity)定義了用戶可以遷移的Activity原子組。Task可以移動(dòng)到前臺(tái)和后臺(tái);在某個(gè)特定Task中的所有Activity總是保持相同的次序。
    這個(gè)標(biāo)志一般用于呈現(xiàn)“啟動(dòng)”類型的行為:它們提供用戶一系列可以單獨(dú)完成的事情,與啟動(dòng)它們的Activity完全無(wú)關(guān)。
    使用這個(gè)標(biāo)志,如果正在啟動(dòng)的Activity的Task已經(jīng)在運(yùn)行的話,那么,新的Activity將不會(huì)啟動(dòng);代替的,當(dāng)前Task會(huì)簡(jiǎn)單的移入前臺(tái)。參考FLAG_ACTIVITY_MULTIPLE_TASK標(biāo)志,可以禁用這一行為。
    這個(gè)標(biāo)志不能用于調(diào)用方對(duì)已經(jīng)啟動(dòng)的Activity請(qǐng)求結(jié)果。

    FLAG_ACTIVITY_NO_ANIMATION
    如果在Intent中設(shè)置,并傳遞給Context.startActivity()的話,這個(gè)標(biāo)志將阻止系統(tǒng)進(jìn)入下一個(gè)Activity時(shí)應(yīng)用Acitivity遷移動(dòng)畫。這并不意味著動(dòng)畫將永不運(yùn)行——如果另一個(gè)Activity在啟動(dòng)顯示之前,沒(méi)有指定這個(gè)標(biāo)志,那么,動(dòng)畫將被應(yīng)用。這個(gè)標(biāo)志可以很好的用于執(zhí)行一連串的操作,而動(dòng)畫被看作是更高一級(jí)的事件的驅(qū)動(dòng)。

    FLAG_ACTIVITY_NO_HISTORY
    如果設(shè)置,新的Activity將不再歷史stack中保留。用戶一離開(kāi)它,這個(gè)Activity就關(guān)閉了。這也可以通過(guò)設(shè)置noHistory特性。

    FLAG_ACTIVITY_NO_USER_ACTION
    如果設(shè)置,作為新啟動(dòng)的Activity進(jìn)入前臺(tái)時(shí),這個(gè)標(biāo)志將在Activity暫停之前阻止從最前方的Activity回調(diào)的onUserLeaveHint()。
    典型的,一個(gè)Activity可以依賴這個(gè)回調(diào)指明顯式的用戶動(dòng)作引起的Activity移出后臺(tái)。這個(gè)回調(diào)在Activity的生命周期中標(biāo)記一個(gè)合適的點(diǎn),并關(guān)閉一些Notification。
    如果一個(gè)Activity通過(guò)非用戶驅(qū)動(dòng)的事件,如來(lái)電或鬧鐘,啟動(dòng)的,這個(gè)標(biāo)志也應(yīng)該傳遞給Context.startActivity,保證暫停的Activity不認(rèn)為用戶已經(jīng)知曉其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中設(shè)置,并傳遞給Context.startActivity(),這個(gè)標(biāo)志將引發(fā)已經(jīng)運(yùn)行的Activity移動(dòng)到歷史stack的頂端。
    例如,假設(shè)一個(gè)Task由四個(gè)Activity組成:A,B,C,D。如果D調(diào)用startActivity()來(lái)啟動(dòng)Activity B,那么,B會(huì)移動(dòng)到歷史stack的頂端,現(xiàn)在的次序變成A,C,D,B。如果FLAG_ACTIVITY_CLEAR_TOP標(biāo)志也設(shè)置的話,那么這個(gè)標(biāo)志將被忽略。

    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
    如果設(shè)置,當(dāng)這個(gè)Activity位于歷史stack的頂端運(yùn)行時(shí),不再啟動(dòng)一個(gè)新的。


    Activity和Task

    之前提到的,一個(gè)Activity可以啟動(dòng)另一個(gè),即便是定義在不同應(yīng)用程序中的Activity。例如,假設(shè)你想讓用戶顯示一些地方的街景。而這里已經(jīng)有一個(gè)Activity可以做到這一點(diǎn),因此,你的Activity所需要做的只是在Intent對(duì)象中添加必要的信息,并傳遞給startActivity()。地圖瀏覽將會(huì)顯示你的地圖。當(dāng)用戶按下BACK鍵,你的Activity會(huì)再次出現(xiàn)在屏幕上。

    對(duì)于用戶來(lái)說(shuō),看起來(lái)好像是地圖瀏覽與你的Activity一樣,屬于相同的應(yīng)用程序,即便是它定義在其它的應(yīng)用程序里,并運(yùn)行在那個(gè)應(yīng)用程序的進(jìn)程里。Android通過(guò)將這兩個(gè)Activity保存在同一個(gè)Task里來(lái)體現(xiàn)這一用戶體驗(yàn)。簡(jiǎn)單來(lái)說(shuō),一個(gè)Task就是用戶體驗(yàn)上的一個(gè)“應(yīng)用”。它將相關(guān)的Activity組合在一起,以stack的方式管理。stack中根Activity啟動(dòng)Task——典型的,它就是用戶在應(yīng)用程序啟動(dòng)欄中選擇的Activity。位于stack頂端的Activity是當(dāng)前正在運(yùn)行的——能夠聚焦用戶的動(dòng)作。當(dāng)一個(gè)Activity啟動(dòng)另一個(gè),新的Activity進(jìn)入stack;它成為正在運(yùn)行的Activity。之前的Activity仍保留在stack中。當(dāng)用戶按下BACK鍵,當(dāng)前的Activity從stack中退出,之前的那個(gè)成為正在運(yùn)行的Activity。

    stack包含對(duì)象,因此,如果一個(gè)Task中有多個(gè)同一個(gè)Activity的實(shí)例時(shí)——多個(gè)地圖瀏覽,例如——stack為每個(gè)實(shí)例擁有一個(gè)獨(dú)立的入口。位于stack中的Activity不會(huì)重新調(diào)整,只是進(jìn)入和退出。

    一個(gè)Task就是一組Activity,不是一個(gè)類或者在manifest中定義的一個(gè)元素。因此,沒(méi)有辦法為Task設(shè)置獨(dú)立于它的Activity的屬性值。Task的值作為整體在根Activity中設(shè)置。例如,下一個(gè)章節(jié)會(huì)討論Task的“affinity”;那個(gè)值就是從Task中的根Activity中讀取的。

    Task中的所有Activity作為一個(gè)單元一起移動(dòng)。整個(gè)Task(整個(gè)Activity stack)可以進(jìn)入前臺(tái)或者退到后臺(tái)。例如,假設(shè)當(dāng)前Task中的stack中有4個(gè)Activity——3個(gè)位于當(dāng)前Activity下方。用戶按下HOME鍵,進(jìn)入到應(yīng)用程序啟動(dòng)欄,然后選擇一個(gè)新的應(yīng)用程序(實(shí)際上,一個(gè)新的Task)。當(dāng)前Task退到后臺(tái),并且新Task中的根Activity會(huì)顯示出來(lái)。然后,經(jīng)過(guò)一段時(shí)間后,用戶回到Home畫面,然后再次選擇前一個(gè)應(yīng)用程序(前一個(gè)Task)。那個(gè)擁有4個(gè)Activity的Task會(huì)進(jìn)入前臺(tái)。當(dāng)用戶按下BACK鍵,屏幕不會(huì)顯示用戶剛剛離開(kāi)的Activity(前一個(gè)Task的根Activity)。而是,這個(gè)stack中的頂端Activity移除,相同Task中的前一個(gè)Activity會(huì)顯示出來(lái)。

    剛才描述的行為是Activity和Task的默認(rèn)行為。但有方法來(lái)完全改變它。Task之間的關(guān)聯(lián),和一個(gè)Task中的一個(gè)Activity行為,受啟動(dòng)Activity的Intent對(duì)象中設(shè)置的Flag和manifest文件中Activity的元素的特性值交互控制。調(diào)用者和響應(yīng)者都有權(quán)決定如何發(fā)生。

    核心的Intent Flag有:
    FLAG_ACTIVITY_NEW_TASK
    FLAG_ACTIVITY_CLEAR_TOP
    FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
    FLAG_ACTIVITY_SINGLE_TOP

    核心的特性有:
    taskAffinity
    launchMode
    allowTaskReparenting
    clearTaskOnLaunch
    alwaysRetainTaskState
    finishOnTaskLaunch

    接下來(lái)的章節(jié)將描述一些Flag和特性的用法,如何相互影響,以及在使用時(shí)的建議。

    Affinity和新Task
    默認(rèn)情況下,一個(gè)應(yīng)用程序中的所有Activity都有affinity——也就是說(shuō),屬于同一個(gè)Task中所有Activity有一個(gè)設(shè)定。然而,每個(gè)Activity都可以在元素的taskAffinity特性上設(shè)置單獨(dú)的值。定義在不同應(yīng)用程序中的Activity可以共享同一個(gè)affinity,或者定義在同一個(gè)應(yīng)用程序中的Activity設(shè)置不同的affinity。Affinity在兩種環(huán)境下工作:Intent對(duì)象包含F(xiàn)LAG_ACTIVITY_NEW_TASK標(biāo)志,和Activity的allowTaskReparenting特性設(shè)置為“true”。
    FLAG_ACTIVITY_NEW_TASK:
    之前描述的,一個(gè)Activity一般通過(guò)調(diào)用startActivity()啟動(dòng)并加入到Task中。它同調(diào)用者一樣,進(jìn)入同一個(gè)Task。然而,如果傳遞給startActivity()的Intent對(duì)象中包含F(xiàn)LAG_ACTIVITY_NEW_TASK時(shí),系統(tǒng)會(huì)搜索一個(gè)新的Task來(lái)容納新的Activity。通常,如標(biāo)志的名字所示,是一個(gè)新的Task。然而,并不是必須是。如果已經(jīng)存在一個(gè)Task與新Activity的affinity相同,這個(gè)Activity就會(huì)加入到那個(gè)Task中。如果不是,啟動(dòng)一個(gè)新的Task。
    allowTaskReparenting:
    如果一個(gè)Activity的allowTaskReparenting特性設(shè)置為“true”,它就能從啟動(dòng)的Task中移到有著相同affinity的Task(這個(gè)Task進(jìn)入到前臺(tái)的時(shí)候)。例如,在一個(gè)旅游的程序中定義了一個(gè)可以報(bào)告選擇城市的天氣情況的Activity。它和同一個(gè)應(yīng)用程序的其它Activity一樣,有著相同的Affinity(默認(rèn)的Affinity),并且它允許重新宿主。你的Activity中的一個(gè)啟動(dòng)了天氣預(yù)報(bào),因此,它初始化到和你Activity相同的Task中。然而,當(dāng)旅游應(yīng)用程序下一次進(jìn)入到前臺(tái)時(shí),天氣預(yù)報(bào)那個(gè)Activity將會(huì)重新編排并在那個(gè)Task中顯示。

    如果從用戶的角度出發(fā),一個(gè).apk文件包含多個(gè)“應(yīng)用”的話,你可能希望為關(guān)聯(lián)的Activity設(shè)置不同的affinity。

    Launch Mode

    這里4種不同的啟動(dòng)模式可以設(shè)置到元素的launchMode特性上:
    standard(默認(rèn)模式)
    singleTop
    singleTask
    singleInstance

    這些模式有以下四點(diǎn)區(qū)別:
    l 哪個(gè)Task將容納響應(yīng)Intent的Activity。對(duì)于“standard”和“singleTop”來(lái)說(shuō),是產(chǎn)生Intent的那個(gè)Task(并調(diào)用startActivity())——除非Intent對(duì)象包含F(xiàn)LAG_ACTIVITY_NEW_TASK。在那種情況下,不同的Task將被選擇,如“Affinity和新Task”中描述的那樣。對(duì)比而言,“singleTask”和“singleInstance”指示Activity總是一個(gè)Task的根。它們定義一個(gè)Task;它們不會(huì)加入到另一個(gè)Task中。
    l 是否有多個(gè)Activity的實(shí)例。“standard”和“singleTop”可以實(shí)例化多次。它們可以屬于多個(gè)Task,一個(gè)特定的Task可以有相同Activity的多個(gè)實(shí)例。對(duì)比而言,“singleTask”和“singleInstance”只能有一個(gè)實(shí)例。因?yàn)檫@些Activity只能位于Task的底部,這一限制意味著在設(shè)備的某個(gè)時(shí)間,不會(huì)出現(xiàn)這樣Task的多個(gè)實(shí)例。
    l 是否可以在同一個(gè)Task中擁有其它的Activity。“singleInstance”Activity保持單身,在它的Task中它是僅有的Activity。如果它啟動(dòng)另一個(gè)Activity,那個(gè)Activity將會(huì)放入到不同的Task中,而不管它的啟動(dòng)模式——好像FLAG_ACTIVITY_NEW_TASK在Intent中一樣。對(duì)于其它方面,,“singleInstance”等同于“singleTask”。其它三個(gè)模式允許多個(gè)Activity加入到這個(gè)Task中。“singleTask”Activity總是位于Task的底部,但它可以啟動(dòng)其它的Activity并放入到它的Task中。“standard”和“singleTop”的Activity可以出現(xiàn)在stack的任何地方。
    l 是否一個(gè)新的實(shí)例啟動(dòng)來(lái)處理新的Intent。對(duì)于默認(rèn)的“standard”來(lái)說(shuō),都是創(chuàng)建一個(gè)新的實(shí)例來(lái)響應(yīng)新的Intent。每個(gè)實(shí)例處理一個(gè)Intent。對(duì)于“singleTop”來(lái)說(shuō),如果它位于目標(biāo)Task的頂端,那么,已經(jīng)存在的實(shí)例就可以重復(fù)使用來(lái)處理這個(gè)新的Intent。如果它不在頂端,那么它就不能重復(fù)使用。替代的,新的實(shí)例將創(chuàng)建來(lái)響應(yīng)新的Intent,并進(jìn)入到stack中。
    例如,假設(shè)一個(gè)Task的Activity stack中包含根Activity A和其它Activity B,C,D,并且D位于頂端,因此,stack是A-B-C-D。有一個(gè)Intent來(lái)了,它要啟動(dòng)D類型的Activity。如果D有默認(rèn)的“standard”啟動(dòng)模式,那么,一個(gè)新的實(shí)例將被啟動(dòng)并且stack變成A-B-C-D-D。然而,如果D的啟動(dòng)模式“singleTop”,已經(jīng)存在的實(shí)例將去處理新來(lái)的Intent(因?yàn)樗锰幵趕tack的頂端),并且stack依舊是A-B-C-D。
    換句話說(shuō),如果來(lái)臨的Intent是沖著B(niǎo)類型的,那么,B類型的實(shí)例將被創(chuàng)建啟動(dòng)而不管B的模式是“standard”或“singleTop”(因?yàn)锽不處在stack的頂端),因此,stack將會(huì)是A-B-C-D-B。
    之前提到的,設(shè)備上不會(huì)出現(xiàn)超過(guò)一個(gè)實(shí)例的“singleTask”或“singleInstance”Activity,因此,那個(gè)實(shí)例都將去處理所有新來(lái)的Intent。“singleInstance”Activity總是位于stack的頂端(因?yàn)樗莟ask中唯一的Activity),因此,它總是處于能處理Intent的位置。然而,“singleTask”Activity可能有或沒(méi)有其它Activity處于它的上方。如果有,它就不處于能處理Intent的位置,那么,這個(gè)Intent將被丟棄。(即使Intent被丟棄了,它的到來(lái)會(huì)引發(fā)那個(gè)Task進(jìn)入到前臺(tái),在那里,它會(huì)繼續(xù)保留。)

    當(dāng)一個(gè)存在的Activity請(qǐng)求去處理一個(gè)新的Intent時(shí),Intent對(duì)象將傳到該Activity的onNewIntent()的方法中。(原來(lái)啟動(dòng)Activity的Intent對(duì)象可以通過(guò)調(diào)用getIntent()得到。)

    注意:當(dāng)一個(gè)新的實(shí)例創(chuàng)建來(lái)處理新的Intent時(shí),用戶可以按下BACK鍵返回到之前的狀態(tài)(前一個(gè)Activity)。但一個(gè)存在的實(shí)例來(lái)處理新的Intent時(shí),用戶不能按下BACK鍵返回到新Intent到來(lái)之前的狀態(tài)。

    清除stack
    如果用戶離開(kāi)Task很長(zhǎng)一段時(shí)間,系統(tǒng)會(huì)清除Task中的所有Activity,除根Activity外。當(dāng)用戶再次返回到這個(gè)Task時(shí),和用戶離開(kāi)時(shí)一樣,僅僅只是初始化Activity呈現(xiàn)。這樣做的意圖是,經(jīng)過(guò)一些時(shí)間后,用戶可能已經(jīng)忘記之前正在做的事情,并且打算回到Task開(kāi)始些新的時(shí)期。

    這是默認(rèn)情況。這里有一些Activity特性可以用于控制這一行為并且修改它:
    alwaysRetainTaskState:
    如果Task的根Activity的這個(gè)特性設(shè)置為“true”時(shí),上面描述的默認(rèn)行為不會(huì)發(fā)生。Task保留所有的Activity,即便是經(jīng)過(guò)很長(zhǎng)一段時(shí)間。
    clearTaskOnLaunch:
    如果Task的根Activity的這個(gè)特性設(shè)置為“true”時(shí),當(dāng)用戶離開(kāi)Task并返回時(shí),stack會(huì)清除直到根Activity。換句話說(shuō),它是alwaysRetainTaskState的另一個(gè)極端。用戶總是回到Task的初始化狀態(tài),即便是一個(gè)短暫的離開(kāi)。
    finishOnTaskLaunch:
    這個(gè)特性和clearTaskOnLaunch相似,但它針對(duì)單個(gè)Activity,不是整個(gè)Task。它能使任何Activity消失,包括根Activity。當(dāng)它設(shè)置為“true”時(shí),這個(gè)Activity僅在當(dāng)前會(huì)話期間保持為Task的部分。如果用戶離開(kāi)并再次返回到這個(gè)Task,它就不再顯示了。

    這里還有其它的方式可以強(qiáng)制Activity從stack中移除。如果Intent對(duì)象中包含F(xiàn)LAG_ACTIVITY_CLEAR_TOP標(biāo)志,并且目標(biāo)Task中已經(jīng)有一個(gè)這個(gè)類型Activity的實(shí)例,而且這個(gè)實(shí)例應(yīng)該處理這個(gè)Intent,那么,位于其上的Activity都將移除,這樣,這個(gè)Activity就能在stack的頂端并響應(yīng)這個(gè)Intent。如果這個(gè)Activity的啟動(dòng)模式設(shè)定為“standard”,它也會(huì)從stack中清除,然后新的實(shí)例啟動(dòng)來(lái)響應(yīng)這個(gè)Intent。這是因?yàn)楫?dāng)啟動(dòng)模式設(shè)定為“standard“時(shí),總是會(huì)創(chuàng)建一個(gè)新的實(shí)例來(lái)響應(yīng)新的Intent。

    FLAG_ACTIVITY_CLEAR_TOP經(jīng)常與FLAG_ACTIVITY_NEW_TASK結(jié)合起來(lái)使用。當(dāng)一起使用時(shí),這些標(biāo)志可以定位其它Task中已經(jīng)存在的Activity,并且把它置于可以響應(yīng)Intent的位置。

    啟動(dòng)Task
    如果一個(gè)Activity的Intent Filter的action為“android.intent.action.MAIN”、category為“android.intent.category.LAUNCHER”時(shí),它就可以作為一個(gè)Task的入口點(diǎn)。有這種類型的Filter會(huì)在導(dǎo)致這個(gè)Activity在應(yīng)用程序啟動(dòng)欄顯示一個(gè)圖標(biāo)和標(biāo)簽,給用戶提供一個(gè)方式可以啟動(dòng)這個(gè)Task和在任何時(shí)候可以再次回到這個(gè)Task。

    第二個(gè)能力很重要:用戶一定可以離開(kāi)一個(gè)Task,然后可以再次回到它。基于這個(gè)原因,兩個(gè)啟動(dòng)模式,“singleTask”和“singleInstance”應(yīng)該只在有MAIN和LAUNCHER的Activity上使用。例如,假設(shè)這個(gè)Filter沒(méi)有的話:一個(gè)Intent啟動(dòng)了一個(gè)“singleTask”Activity,初始化一個(gè)新的Task,然后用戶花費(fèi)了一些時(shí)間在它上面。然后,用戶按下HOME鍵。現(xiàn)在,這個(gè)Task處于后臺(tái)并且被HOME畫面遮蓋。由于它不能在應(yīng)用程序啟動(dòng)欄顯示,用戶就沒(méi)有辦法可以返回它。

    在面對(duì)FLAG_ACTIVITY_NEW_TASK時(shí),也有相似的困難。如果這個(gè)標(biāo)志導(dǎo)致一個(gè)Activity啟動(dòng)了一個(gè)新的Task,并且用戶按下HOME鍵離開(kāi)它,這里必須有方法可以再次回到它。一些機(jī)能(如Notification Manager)總是在外部的Task中啟動(dòng)Activity,而不是作為自己的一部分,因此,它總是把FLAG_ACTIVITY_NEW_TASK標(biāo)志放入Intent,然后傳遞給startActivity()。如果你的Activity可能會(huì)被外部的機(jī)能(可能使用這個(gè)標(biāo)志)調(diào)用,注意用戶可以額外的方式可以返回到啟動(dòng)的Task。

    如果你不想用戶回到某個(gè)Activity,可以把元素的finishOnTaskLaunch設(shè)置為“true”。

    http://www.cnblogs.com/xirihanlin/archive/2010/06/03/1750811.html
    posted on 2010-11-19 14:32 calvin 閱讀(254) 評(píng)論(0)  編輯  收藏 所屬分類: Android
    主站蜘蛛池模板: 精品在线免费视频| 青青操免费在线视频| 亚洲情a成黄在线观看| 日本一卡精品视频免费| 国产亚洲精品美女久久久久| 亚洲国产精品无码专区影院| 妻子5免费完整高清电视| 黄页网站在线视频免费| 亚洲精品综合一二三区在线| 日本一道综合久久aⅴ免费| a级片免费观看视频| 亚洲精品永久在线观看| 亚洲国产精品成人精品无码区| 女性自慰aⅴ片高清免费| 青青青国产手机频在线免费观看 | 亚洲综合一区二区| 免费在线观看一级毛片| 69pao强力打造免费高清| 污污视频网站免费观看| 亚洲国产av高清无码| 亚洲色精品88色婷婷七月丁香| 成人免费视频一区二区三区| 日韩成人免费视频| 污视频网站在线观看免费| 亚洲a级在线观看| 亚洲精品无码国产| 免费少妇a级毛片人成网| 成年免费大片黄在线观看岛国| 中文字幕免费不卡二区| 美女视频黄频a免费| 亚洲一卡2卡3卡4卡5卡6卡| 亚洲精品私拍国产福利在线| 亚洲高清免费视频| 日韩毛片免费在线观看| 人与禽交免费网站视频| 精品一卡2卡三卡4卡免费视频| h片在线观看免费| 欧美色欧美亚洲另类二区| 国产成人精品亚洲2020| 亚洲精品韩国美女在线| 久久香蕉国产线看观看亚洲片|