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”,這個特性勝出,Activity的affinity忽略。這個Activity不會重新宿主,但是會銷燬。
通過Intent設定的屬性標識:
形式如下:Intent intent = new Intent(SwitchActivity.this, ThredActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
在預設情況下,一個新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處啟動一個Activity3、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 進行學習。
相關文章
- 與 AI 互動 - 學習如何看呼叫鏈堆疊資訊AI
- 「前端」History API與瀏覽器歷史堆疊管理前端API瀏覽器
- android I/DEBUG堆疊資訊Android
- QT分局管理:堆疊窗體(三)QT
- 陣列、連結串列、堆疊和佇列學習陣列佇列
- CSS之定位和堆疊屬性CSS
- Android之ActivityAndroid
- JS 堆疊JS
- java堆疊Java
- 堆疊圖
- 平衡堆疊
- 安卓學習筆記之Activity(一)安卓筆記
- 從零開始的堆疊卡片控制元件控制元件
- android 解碼混淆過的堆疊資訊Android
- 不一樣的 Android 堆疊抓取方案Android
- Python實現堆疊與佇列Python佇列
- JS中堆疊記憶體的練習JS記憶體
- Go 錯誤堆疊資訊之 CockroachDB errors 庫GoError
- 初探堆疊欺騙之靜態欺騙
- Android知識點複習1(Activity與Fragment)AndroidFragment
- Android學習筆記-Activity的啟動模式Android筆記模式
- 圖的深度優先遍歷[非堆疊、堆疊實現]
- 《Android藝術開發探索》學習筆記之Activity的生命週期Android筆記
- Andoroid學習筆記05——Activity佈局管理筆記
- Android之Activity全面解析Android
- Android Apt之Activity RouteAndroidAPT
- 堆的學習
- 記憶體堆疊記憶體
- 堆疊的工作原理
- C#堆疊(Stack)C#
- sql注入之堆疊注入及waf繞過注入SQL
- 再探堆疊欺騙之動態欺騙
- 三探堆疊欺騙之Custom Call Stacks
- Java堆疊的深度分析及記憶體管理技巧Java記憶體
- Android學習筆記04——Activity的生命週期Android筆記
- Android基礎之Activity 執行模式與回退棧Android模式
- Android Activity 重建之狀態儲存與恢復Android
- 學習筆記 AS入門(四) 元件篇之Activity筆記元件