天天看點

activity的啟動模式和棧管理 1.什麼是棧 3.Task 4.Activity啟動模式 5.Activity棧和Task聯系 6.Intent Flags  7.Activity相關屬性taskAffinity

 在學習android的過程中,intent是我們最常用android用于程序内或程序間通信的機制,其底層的通信是以binder機制實作的,在實體層則是通過共享記憶體的方式實作的。

    intent主要用于2種情景下:(1)發起意圖

 (2)廣播

    它的屬性有:componentname,action,data,category,extras,flags等,通常情況下,進行intent的比對涉及到3個屬性:action,data,category。這些東西都需要了解才能對它有個深入的體會。

    下面我就根據近期學習,總結記錄下activity啟動模式

及 intent flags 與 棧 的關聯分析。

文章結構:

1.什麼是棧

2.activity棧

3.task

4.activity啟動模式

5.activity棧和task聯系

6.intent flags 

7.activity相關屬性taskaffinity

task是與activity相關的一個重要概念,它密切聯系着activity棧,它簡單的說,就是一組以棧的模式聚集在一起的activity元件集合。(這裡隻提它和activity的啟動模式來講)

屬性:android:launchmode  

作用:用于訓示activity如何啟動。

描述:這裡有四種模式,與intent對象中的activity flags的屬性(flag_activity_*變量)共同作用,來決定activity如何啟動來處理intent。

四種模式:

    "standard"  --預設模式

    "singletop"

    "singletask"

    "singleinstance"

以下舉例說明它們的差別:

standard:activity的預設加載方法,該方法會通過跳轉到一個新的activity,同時将該執行個體壓入到棧中(不管該activity是否已經存在在task棧中,都是采用new操作)。例如:

棧中順序是a b c d ,此時d通過intent跳轉到a,那麼棧中結構就變成 a b c d a ,點選傳回按鈕的 顯示順序是 d c b a,依次摧毀。

singletop:singletop模式下,目前activity

d位于棧頂的時候,如果通過intent跳轉到它本身的activity (即d),那麼不會重新建立一個新的d執行個體,是以棧中的結構依舊為a b c d,如果跳轉到b,那麼由于b不處于棧頂,是以會建立一個b執行個體并壓入到棧中,結構就變成了a b c d b。

singletask:singletask模式下,task棧中隻能有一個對應activity的執行個體。例如:現在棧的結構為:a

b c d。此時d通過intent跳轉到b,則棧的結構變成了:a b。其中的c和d被棧彈出銷毀了,也就是說位于b之上的執行個體都被銷毀了。

singleinstance:singleinstance模式下,會将打開的activity壓入一個建立的任務棧中。例如:task棧1中結構為:a

b c ,c通過intent跳轉到了d(d的模式為singleinstance),那麼則會建立一個task 棧2,棧1中結構依舊為a b c,棧2中結構為d,此時螢幕中顯示d,之後d通過intent跳轉到d,棧2中不會壓入新的d,是以2個棧中的情況沒發生改變。如果d跳轉到了c,那麼就會根據c對應的launchmode的在棧1中進行對應的操作,c如果為standard,那麼d跳轉到c,棧1的結構為a

b c c ,此時點選傳回按鈕,還是在c,棧1的結構變為a b c,而不會回到d。

task簡單的就是一組以棧的模式聚集在一起的activity元件集合,類似于一個填充了activity的容器,最先加入的activity會處于容器最下面,最後加入的處于容器最上面,而從task中取出activity是從最頂端先取出,最後取出的是最開始添加activity,這就是後進先出(last

in first out)模式,而activity在task中的順序是可以控制的,在activity跳轉時用到intent flag可以設定建立activity的建立方式(這裡就涉及到了intent flag的使用)。

flags: 表示intent的标志位,常用于activity的場景中,它和activity的啟動模式有着密切的聯系。

下面列舉的是和本文主題相關的flags屬性:

intent.flag_activity_new_task

(預設)

預設的跳轉類型,它會重新建立一個新的activity,不過與這種情況,比如說task1中有a,b,c三個activity,此時在c中啟動d的話,如果在androidmanifest.xml檔案中給d添加了affinity的值和task中的不一樣的話,則會在新标記的affinity所存在的task中壓入這個activity。如果是預設的或者指定的affinity和task一樣的話,就和标準模式一樣了啟動一個新的activity.

flag_activity_single_top

這個flag就相當于啟動模式中的singletop,例如:原來棧中結構是a b c d,在d中啟動d,棧中的情況還是a,b,c,d。

flag_activity_clear_top

這個flag就相當于啟動模式中的singletask,這種flag啟動的activity會把要啟動的activity之上的activity全部彈出棧空間。例如:原來棧中的結構是a

b c d ,從d中跳轉到b,棧中的結構就變為了a b了。(這個方法可以用來關閉多個activity,之後的一篇博文裡面會提到)

flag_activity_brought_to_front

這個網上很多人是這樣寫的。如果activity在task存在,拿到最頂端,不會啟動新的activity。這個有可能會誤導大家! 他這個flag其實是這個意思!比如說我現在有a,在a中啟動b,此時在A中intent中加上這個标記。此時b就是以flag_activity_brought_to_front方式啟動,此時在b中再啟動c,d(正常啟動c,d),如果這個時候在d中再啟動b,這個時候最後的棧的情況是

a,c,d,b。如果在a,b,c,d正常啟動的話,不管b有沒有用flag_activity_brought_to_front啟動,此時在d中啟動b的話,還是會變成a,c,d,b的。

flag_activity_no_user_action

onuserleavehint()作為activity周期的一部分,它在activity因為使用者要跳轉到别的activity而要退到background時使用。比如,在使用者按下home鍵,它将被調用。比如有電話進來(不屬于使用者的選擇),它就不會被調用。

那麼系統如何區分讓目前activity退到background時使用是使用者的選擇?

它是根據促使目前activity退到background的那個新啟動的activity的intent裡是否有flag_activity_no_user_action來确定的。

注意:調用finish()使該activity銷毀時不會調用該函數

flag_activity_no_history

意思就是說用這個flag啟動的activity,一旦退出,它不會存在于棧中,比方說!原來是a,b,c這個時候再c中以這個flag啟動d的,d再啟動e,這個時候棧中情況為a,b,c,e。

activity

中的 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名。

注:以上的android:taskaffinity隻有通過标志位為flag_activity_new_task的intent啟動activity時,該activity的這個屬性才會生效,系統才會将具有相同task親和力的task切換到前台,然後啟動該activity,否則該activity仍然運作在啟動它的task中。

  上面總結了下activity啟動模式 及 intent flags 與 棧 的關聯分析,便于之後一篇文章中跳轉模式的了解使用。

繼續閱讀