Android學習之 Activity堆棧管理與控制

    App程序中有很多Activity、你可以通俗的理解爲把一個Activity看做是一個UI界面。在Andord系統中Activity是以堆棧<堆棧的特性:只有壓入和彈出  先進後出>的形式存在。堆棧中的根Activity就是應用程序的啓動Activity。而堆棧中最上方的Activity則是當前運行的/用戶正在操作的UI Activity。

    也可以這樣去理解:堆棧中保存的是Activity對象,如果一個應用中多次使用了一個Activity,那麼就會使同一個任務中出現多個該Activity的對象。一個程序在運行、他所啓動的Activity通常情況下<注意是通常情況下>在同一個堆棧中、這個也叫做任務棧<Task>。

    Activity和Task的關聯: Activity在任務中的行爲,受控於啓動Activity的行爲對象的標誌位和清單文件中的<activity> 元素的屬性的互相作用。

    

主要的行爲標誌有:

FLAG_ACTIVITY_NEW_TASK 

FLAG_ACTIVITY_CLEAR_TOP 

FLAG_ACTIVITY_SINGLE_TOP

..............等


主要的<activity>屬性有:

launchMode 

taskAffinity 

allowTaskReparenting 

alwaysRetainTaskState

clearTaskOnLaunch 

finishOnTaskLaunch


下面將對每一個屬性和標誌一一介紹:

[雖然全是文字說明,稍有枯味、但只要你細細消化 相信使你對Activity棧的管理會進一步理解]

<activity>屬性:

1、launchMode:Activity 4種啓動模式  

     1>、standard: <默認啓動模式>

           在任務棧中總是創建一個新的Activity實例

     2>、singleTop:

           在任務棧中如果有存在一個和新啓動Activity相同的Activity正在棧頂則不再創建一個新的Activity,即不再調         用onCreate(),而是通過調用onNewIntent()方法。如果不存在棧頂,這時候就和standard一樣創建一個新的             Activity實例,走onCreate()方法。

      3>、singleTask:

             ①設置了"singleTask"啓動模式的Activity,它在啓動的時候,會先在系統中查找屬性值affinity等於它的屬性        值taskAffinity的Task存在;如果存在這樣的Task,它就會在這個Task中啓動,否則就會在新的任務棧中啓動。        因此,如果我們想要設置了"singleTask"啓動模式的Activity在新的任務中啓動,就要爲它設置一個獨立的taskAffinity屬性值。

            ② 如果設置了"singleTask"啓動模式的Activity不是在新的任務中啓動時,它會在已有的任務中查看是否已經        存在相應的Activity實例,如果存在,就會把位於這個Activity實例上面的Activity全部結束掉,即最終這個Activity 實例會位於任務的Stack頂端中。

            ③ 在一個任務棧中只有一個”singleTask”啓動模式的Activity存在。他的上面可以有其他的Activity。這點與singleInstance是有區別的。

       4>、singleInstance:

             在一個新的任務棧中啓動,且該棧中有且只有他一個Activity實例、不允許有其他的Activity成員存在。

             永遠他一個。


2、android:taskAffinity: task親和力

      通常來說一個程序內/任務棧中的Activity具有親和力,也就是說具有相同親和力的Activity默認屬於同一個任務Task中,

     affinity決定兩件事情——Activity重新宿主(從一個Task跳到了另一個Task中,新的Task就被稱爲重新宿主)的Task(參考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK標誌啓動的Activity宿主的Task。

     默認情況,一個應用程序中的所有Activity都擁有相同的affinity。你可以通過設定這個特性來重組它們,甚至可以把不同應用程序中定義的Activity放置到相同的Task中。如果不指定改activity到底屬於哪個task,則可以將affinity設置爲空字符串。如果這個特性沒有設置,Activity將從應用程序的設定那裏繼承下來(參考<application>元素的taskAffinity特性)。應用程序默認的affinity的名字是<manifest>元素中設定的package名。

      注意:affinity只有在加載activity的Intent對象包含了FLAG_ACTIVITY_NEW_TASK 標記,或者當activity的allowTaskReparenting屬性設置爲“true”時纔有效。


3、android:allowTaskReparenting:是否允許Activity跳轉/更改Task

     用來標記Activity能否從啓動的Task移動到有着相同affinity的Task(當這個Task進入到前臺時)——“true”,表示能移動,“false”,表示它必須呆在啓動時的那個Task裏。如果這個特性沒有被設定,設定到<application>元素上的allowTaskReparenting特性的值會應用到Activity上。默認值爲“false”。

      一般來說,當Activity啓動後,它就與啓動它的Task關聯,並且在那裏耗盡它的整個生命週期。噹噹前的Task不再顯示時,你可以使用這個特性來強制Activity移動到有着affinity的Task中。典型用法是:把一個應用程序的Activity移到另一個應用程序的主Task中。


4、android:alwaysRetainTaskState:當按下Home主鍵將程序退回至後臺運行,再回到前臺時是否保留Task狀態

     用來標記Activity所在的Task的狀態是否總是由系統來保持——“true”,表示總是;“false”,表示在某種情形下允許系統恢復Task到它的初始化狀態。默認值是“false”。這個特性只針對Task的根Activity有意義;對其它Activity來說,忽略之。

     一般來說,特定的情形如當用戶從主畫面重新選擇這個Task時,系統會對這個Task進行清理(從stack中刪除位於根Activity之上的所有Activivity)。典型的情況,當用戶有一段時間沒有訪問這個Task時也會這麼做,例如30分鐘。

然而,當這個特性設爲“true”時,用戶總是能回到這個Task的最新狀態,無論他們是如何啓動的。這非常有用,例如,像Browser應用程序,這裏有很多的狀態(例如多個打開的Tab),用戶不想丟失這些狀態。系統會爲我們保持這些狀態數據。


5、android:clearTaskOnLaunch:當按下Home主鍵將程序退回至後臺運行,再回到前臺時是否清除/移除除了跟Activity<啓動Activity>之外的所有Activity。

     用來標記是否從Task中清除所有的Activity,除了根Activity外(每當從主畫面重新啓動時)——“true”,表示總是清除至它的根Activity,“false”表示不。默認值是“false”。這個特性只對啓動一個新的Task的Activity(根Activity)有意義;對Task中其它的Activity忽略。

    當這個值爲“true”,每次用戶重新啓動這個Task時,都會進入到它的根Activity中,不管這個Task最後在做些什麼,也不管用戶是使用BACK還是HOME離開的。當這個值爲“false”時,可能會在一些情形下(參考alwaysRetainTaskState特性)清除Task的Activity,但不總是。

    假設,某人從主畫面啓動了ActivityP,並從那裏遷移至Activity Q。接下來用戶按下HOME,然後返回Activity P。一般,用戶可能見到的是Activity Q,因爲它是P的Task中最後工作的內容。然而,如果P設定這個特性爲“true”,當用戶按下HOME並使這個Task再次進入前臺時,其上的所有的Activity(在這裏是Q)都將被清除。因此,當返回到這個Task時,用戶只能看到P。如果這個特性和allowTaskReparenting都設定爲“true”,那些能重新宿主的Activity會移動到共享affinity的Task中;剩下的Activity都將被拋棄。


6、android:finishOnTaskLaunch:當按下Home主鍵將程序退回至後臺運行,再回到前臺時是否關閉/結束掉退回到後臺之前的Activity.

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



通過Intent設置的屬性標識:

形式如下:

Intent intent = new Intent(SwitchActivity.this, ThredActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);


1、FLAG_ACTIVITY_NEW_TASK

     在默認情況下,一個新Activity被另一個Activity調用了startActivity()方法,載入任務之中。並壓入了調用者所在的堆棧。然而,如果傳遞給startActivity()Intent對象包含了FLAG_ACTIVITY_NEW_TASK標記,系統會爲新Activity安排另外一個任務。一般情況下,如同標記所暗示的那樣,這會是一個新任務。然而,這並不是必然的。如果已經存在了一個與新Activity有着同樣affinity的任務,則Activity會載入那個任務之中。如果沒有,則啓用新任務。

簡言之:有相同affinity的任務,則壓入該任務,否則創建一個新的任務。


2、FLAG_ACTIVITY_CLEAR_TOP

      如果intent將要啓動的Activity已經存在於一個Task中,那麼這個Task中該Activity上面的那些Activity都會被移除銷燬,然後這個intent將會作爲一個新的intent投遞給目標Activity(目標Activity已經位於棧的頂端了)。

     這個啓動模式還可以與FLAG_ACTIVITY_NEW_TASK結合起來使用:用於啓動一個Task中的根Activity,它會把那個Task中任何運行的實例帶入前臺,然後清除它直到根Activity。這非常有用,例如,當從NotificationManager處啓動一個Activity


3、FLAG_ACTIVITY_SINGLE_TOP

     如果設置,當這個Activity位於歷史stack的頂端運行時,不再啓動一個新的。
     同 android: launchMode = “singleTop”


4、FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

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


以上只介紹了常有用的幾種控制Activity跳轉的Flag標識

更多詳細前往 http://android.toolib.net/reference/android/content/Intent.html 進行學習。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章