3.Activity的啓動模式與任務棧學習筆記

    本來自認爲對Activity啓動模式已經很熟悉了,但是還是有一些忘了,所以在此我再次學習一遍。
    首先,Activity的啓動模式分爲四種,爲了滿足各種項目的需求,我們需要了解Activity的啓動模式和標誌位。

3.1 Activity的LaunchMode
    
    3.1.1 standard:標準模式,也就是系統的默認模式。
    每次啓動一個Activity都會創建一個新的實例,不管這個Activity是否已經存在了實力,多次啓動的Activity聲明週期也是符合正常情況下的生命週期.這是一種典型的多實例實現,一個任務棧中可以有多個實例,每個實例也可以屬於不同的任務棧。在這個情況下,誰啓動了這個Activity,那麼這個Activity就會運行在啓動它的那個Activity所在的棧當中。
    在這裏說明一種情況:使用ApplicationContext去啓動Standard模式的Activity的時候,會報錯,如下:
    android.util.AndroidRuntimeException:   Calling startActivity from outside of an Activity requires the FLAG_ACTIVITY_NEW_TASK flag.Is this really what you want ?
    這個錯誤經常會遇到,比如在一個廣播當中直接用Context去啓動一個新的標準的Activity.這個是因爲,standard模式的Activity默認會進入啓動它的Activity的任務棧,而非Activity類型的Context(比如ApplcationContext)是沒有任務棧的,所以就會出現問題。解決這個就是啓動的時候設置標誌:FLAG_ACTIVITY_NEW_TASK。這樣子就會爲這個Activity創建一個單獨的任務棧,這個時候待啓動的Activity實際上是用singleTask來啓動的(按照不存在的方式啓動)。

    3.1.2 singleTop:棧頂複用模式。
    在這種情況下,如果要創建的Activity已經有實例位於任務棧的棧頂,那麼就不會被重新創建,但是會調用這個Activity的onNewIntent方法(onCreate、onResume方法不會被調用),通過onNewIntent方法,我們可以從Intent當中取出請求的信息。

    3.1.3 singleTask:棧內複用模式。
    這是一種單實例模式,這種模式下,只要Activity一個棧中存在該Activity的實例,那麼多次調用都不會創建新的實例,但是系統會調用它的onNewIntent。
    具體來哦說:當一個具有singleTask模式的Activity請求啓動以後,比如Activity A,系統首先會尋找是否存在A想要的任務棧。如果不存在,就重新創建一個任務棧,如果不存在,就創建新的一個任務棧,然後創建A的實例放到棧中,如果存在,就看這個任務棧是否有A的實例存在,如果有實例存在,那麼系統則會把A調到棧頂然後再移除該實例上面的Activity並且調用它的onNewIntent方法。如果A不在這個想要的任務棧中,那麼就會創建A的實力並且把A壓入棧中。
  • 比如任務棧S1有ABC,singleTask啓動Activity D,D想進入S2,沒有S2也沒有D,那麼就創建S2,並且把D放入S2中。
  • D所需要S1,S1存在,D不存在,那麼就創建D放入S1。最後S1爲ABCD
  • 再一種情況,S1存在,D也存在,D想進S1,順序爲ADBC,那麼就會把D放到棧頂,而D前面的都會被clear掉。
   
    3.1.4 singInstance:單實例模式。
        這種模式是加強版本的singleTask模式,這種模式的Activity只能單獨位於一個棧當中。
   
    3.1.5 指定啓動模式
        指定啓動模式有兩種:一種是在AndroidManifest.xml中,在Activity聲明裏面指定啓動模式比如:
<activity android:name=".Main2Activity"
android:allowTaskReparenting="true"
android:launchMode="singleTask"
></activity>


    也可以通過再Intent中設置標誌位來爲Activity指定啓動模式,如:
    Intent intent = new Intent();
    intent.setClass( MainActivity.Class,SecondActivity.class);
    startActivity( intent );
    
    這兩種方式,都可以爲Activity指定啓動模式,但是兩者還是有區別。
  • 優先級上:第二種高於第一種。
  • 限定範圍不同,第一種無法直接爲Activity標誌:FLAG_ACTIVITY_CLEAR_TOP(但是singleTask默認具有這個功能),第二種無法爲Activity指定singleInstance
    
3.2 任務棧

    什麼是任務棧呢?要了解Task棧,就需要先了解:
  • Activity的affinity
  • Intent的Flag
  • Activity關於Task的屬性    
    在此,我們先從參數TaskAffinity說起。

    3.2.1 TaskAffinity
            TaskAffinity可以翻譯爲:任務相關性。它是一個參數,這個參數標識了一個Activity所需要的任務棧的名字。也就是我們上面介紹SingleTask所說的需要的任務棧。默認情況下,這個所有Activity所需要的棧名就是包名(包名是唯一的)。當然,我們可以爲每個Activity都單獨制定TaskAffinity屬性,這個屬性值必須不能和包名一樣(不只是自己的包名,和其他應用包名都不能重複),否則就相當於沒有指定。TaskAffinity屬性主要和singleTask啓動模式或者allowTaskReparenting屬性配對使用,在其他情況下沒有意義。另外,任務棧又分:前臺任務棧和後臺任務棧。後臺任務棧的Activity位於暫停狀態,用戶可以通過切換把後臺任務棧再次調到前臺。(如何調用呢?參考:http://blog.csdn.net/chaoyue0071/article/details/43791909  稍後也會進行解釋
    
    當TaskAffinity和singleTask啓動模式配對使用的時候,它是具有該模式的Activity的目前棧的名字,待啓動的Activity會運行在名字和TaskAffinity相同的任務棧中。
    當TaskAffinity和allTaskReparenting結合的時候,會產生一些特殊的效果。比如應用A啓動了應用B的某個Activity後,如果這個Activity的allTaskReparenting屬性爲True的話,那麼當應用B被啓動後,此Activity會直接從應用A的任務棧移到應用B的任務棧。   如:A應用和B應用,A應用啓動了B的某一個Activity C,然後按Home回到了桌面,最後單擊B應用,跳出來的是B應用的Activity C而不是MainActivity。  
    問題:TaskAffinity和singleTask搭配時候,和TaskAffinity +allTaskReparenting 有什麼區別?     
    區別在於:前者創建Activity C的時候就會創建B的任務棧 ,而後者則是現在A的任務棧運行,等到了B啓動,創建了任務棧B,那麼就會把C從任務棧A移到任務棧B當中。   

3.2.2 Activity的常用Flags
  • FLAG_ACTIVITY_NEW_TASK
        指定Activity啓動模式爲"singleTask"模式,效果和在AndroidManifest.xml中指定該啓動模式一樣。
  • FLAG_ACTIVITY_SINGLE_TOP
        指定Activity啓動模式爲"singleTop"模式。
  • FLAG_ACTIVITY_CLEAR_TOP 
       使用這個標記位,啓動Activity的時候,通一個任務棧上面所有位於它上面的Activity都會被彈出棧。singleTask模式默認有此效果。
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
        這個Activity不會出現在歷史Activity的列表當中,在一些情況下,我們不希望用戶能通過歷史列表找回這個Activity,那麼我們可以使用這個標記位。可以在AndroidManifest.xml中使用android:excludeFromRecents="true"。B標記了,比如A->B->C,C按返回鍵會回到A。


3.3 前臺任務棧和後臺任務棧

       個人認爲:前臺任務棧是當前運行於前臺的一組Activity的集合,也可以是Activity集合的集合,比如棧A運行於前臺,棧B運行於後臺,棧A調用棧B的Activity,那麼,棧B就會運行到前臺,並且棧B整個Activity列表疊在棧A的Activity列表上,如果一直按Back會清空棧B以後,才進入到棧A。而此時棧A、棧B都運行於前臺。當按了Home鍵什麼的,棧A和棧B就雙雙進入後臺暫停運行。




發佈了30 篇原創文章 · 獲贊 17 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章