[譯]Android應用程式基底礎 >> 任務棧和親屬關係(Activities and Tasks)

來源:互聯網
上載者:User

    在android中,一個activity組件可以啟用另一個activity組件(可能屬於另一個應用程式)。

    若新的被啟用的activity組件屬於另一個應用程式,則那個activity組件會運行在那個應用程式的進程中,但是從使用者的角度來看,好像就是屬於本應用程式一樣。Android是通過將之前的activity組件和新被啟用的activity組件放入同一個任務棧來實現這個功能的。從使用者的角度看,一個任務棧就代表了“一個應用程式”。它實際上是一個棧,裡面放著一組被排列好的相關的activity組件。位於棧底的activity(根activity)就是開啟這個任務棧的activity組件,一般情況下,就是應用程式的主介面。而位於棧頂的activity組件即代表當前被啟用的activity組件(可接收使用者行為的activity)

    任務棧中包含了activity組件的對象,且任務棧中可以包含有某一個activity組件類型的多個執行個體對象。在任務棧中的activity組件不能被重排序,只能被壓棧和彈棧。

    任務棧不是某個類型,也不是某一個元素,它是一組activity組件的組織形式。所以沒有辦法在不影響任務棧中的activity組件的情況下,單獨設定任務棧的參數。根activity的參數既是整個任務棧的參數,它會影響任務棧中的所有activity組件。

    當某個應用程式在前後台切換的時候,實際上就是代表這個應用程式的一個任務棧在前後台切換。

    剛剛描述的行為是activity和任務棧的預設行為,但也有辦法在很多方面對它進行修改:

    方法1:在發送的請求(即Intent對象)中設定一些標記。

    方法2:在manifest檔案中,對接收請求(即Intent對象)的activity組件設定一些屬性。

    所以在要求者和接收者中都可以進行控制。

在Intent對象中主要的標誌有:

    FLAG_ACTIVITY_NEW_TASK

    FLAG_ACTIVITY_CLEAR_TOP

    FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

    FLAG_ACTIVITY_SINGLE_TOP

在<activity>標籤中,主要的屬性有:

    taskAffinity 

    launchMode 

    allowTaskReparenting 

    clearTaskOnLaunch 

    alwaysRetainTaskState 

    finishOnTaskLaunch

    接下來的內容就會講解一些Intent標誌和<activity>標籤屬性的作用和用法。

1.親屬關係和新的任務

    預設情況下,一個應用程式中的activity組件彼此之間是親屬關係――也就是說它們屬於同一個任務棧。但是我們可以通過設定某個<activity>標籤的taskAffinity屬性來為這個activity組件設定親屬關係。在不同的應用程式中定義的activity組件可以共用同一個親屬關係,或者在同一個的應用程式中定義的activity組件可以使用不同的親屬關係。親屬關係會在兩種情況下發揮作用:

    1)負責啟用activity組件的Intent對象中包含了FLAG_ACTIVITY_NEW_TASK標誌。

    2)被啟用的activity組件的allowTaskReparenting屬性被設定為“true”。

關於FLAG_ACTIVITY_NEW_TASK標誌量

    預設情況下,一個被啟用的新activity會和負責啟用它的那個activity組件存在於同一個任務棧中。但是若負責啟用的Intent對象包含了FLAG_ACTIVITY_NEW_TASK標誌,則系統會為存放那個即被啟用的新activity尋找一個新的任務棧。此時,若已經存在了相同親屬關係的任務棧,則系統會直接將這個即被啟用的新activity放入到這個任務棧中;否則系統會開始一個新的任務棧。

關於allowTaskReparenting屬性

    若一個activity組件的allowTaskReparenting被置為“true”,則當與這個activity有相同的親屬關係的任務棧被切換到前台的時候,這個activity會從當前存在的任務棧中移動到與其有相同的親屬關係的任務棧中。

    若從使用者的角度來看,一個.apk檔案包含了一個以上的“應用程式”,那你可能要為那些activity組件指定不同的親屬關係。

2.啟動模式

<activity>標籤的launchMode屬性可以設定為四種不同的模式:

    “standard”(預設模式)

    “singleTop”

    “singleTask”

    “singleInstance”

    這幾種模式的區別體現以下四點上:

    1)當這個activity被啟用的時候,會放入哪個任務棧。

    對於“standard”和“singleTop”模式,這個新被啟用的activity會放入和之前的activity相同的任務棧中――除非如前所述,Intent對象包含FLAG_ACTIVITY_NEW_TASK標誌。

    但“singleTask”和“singleInstance”模式則表示這個新被啟用的activity不會放入已經存在的任務棧中,它會重新開啟一個任務棧,並作為這個新的任務棧的根activity。

    2)是否可以存在這個activity類型的多個執行個體。

    對於“standard”和“singleTop”模式,可以有多個執行個體,並且這些執行個體可以屬於不同的任務棧,每個任務棧也可以包含有這個activity類型的多個執行個體。

    但“singleTask”和“singleInstance”模式則表示至多隻可以存在這個activity類型的一個執行個體。又因為有第一點必須是根activity的限制,所以這意味著在同一時間,在手機上絕不會存在多於一個的由這個activity啟動的任務棧。

    3)包含此activity的任務棧是否可以包含其它的activity。

    “singleInstance”模式表示包含此activity的任務棧不可以包含其它的activity。若此activity啟動了另一個activity組件,那麼無論那個activity組件的啟動模式是什麼或是Intent對象中是否包含了FLAG_ACTIVITY_NEW_TASK標誌,它都會被放入另外的任務棧。在其它方面“singleInstance”模式和“singleTask”模式是一樣的。

    其餘三種啟動模式則允許包含此activity的任務棧包含其它的activity。

    4)Whether a new instance of the class will be launched to handle a new intent.

    對於預設的“standard”模式,每當響應一個Intent對象,都會建立一個這種activity類型的新的執行個體。即每一個activity執行個體處理一個intent。

    對於“singleTop”模式,只有當這個activity的執行個體當前處於任務棧的棧頂位置,則它會被重複利用來處理新到達的intent對象。否則就和“standard”模式的行為一樣。

    正如第二點所說的,“singleTask”和“singleInstance”模式表示只能有一個執行個體,所以這個唯一的執行個體需要處理所有新到達的intent對象。又由於“singleInstance”模式的activity執行個體總是位於任務棧的棧頂,所以這樣做很正常。但對於“singleTask”模式的acitvity,在其上面可能存在其它的activity組件,所以它的位置並不是棧頂,在這種情況下,intent對象會被丟棄。(雖然會被丟棄,但是這個intent對象會使這個任務棧切換到前台)

    如果一個新到達的intent對象是被一個已經存在的activity組件來處理的,那麼這個activity的onNewIntent(android.content.Intent)方法會被系統調用。

    注意:若為了處理一個新到達的intent對象而建立了一個activity執行個體,則使用者按下“BACK”鍵就會退到之前的那個activity。但若這個新到達的intent對象是由一個已經存在的activity組件來處理的,那麼使用者按下“BACK” 鍵就不會回退到處理這個新intent對象之前的狀態了。

3.清理任務棧

    如果一個任務棧在很長的一段時間都被使用者保持在背景,那麼系統就會將這個任務棧中除了根activity以外的其它所有activity全部清除掉。從這之後,當使用者再將任務棧切換到前台,則只能顯示根activity了。

以上說的是預設模式,可以通過<activity>標籤的一些屬性來更改:

    1)alwaysRetainTaskState屬性

    如果將根activity的alwaysRetainTaskState屬性設定為“true”,則即便一個任務棧在很長的一段時間都被使用者保持在背景,系統也不會對這個任務棧進行清理。

    2)clearTaskOnLaunch屬性

    如果將根activity的clearTaskOnLaunch屬性設定為“true”,那麼只有這個任務棧切換到了後台,那麼系統就會將這個任務棧中除了根activity以外的其它所有activity全部清除掉。即和alwaysRetainTaskState的行為完全相反。

    3) finishOnTaskLaunch屬性

    這個屬性的行為類似於clearTaskOnLaunch,但是此屬性作用於單個的activity對象,而不是整個任務棧。當這個任務棧切換到了後台,這個屬性可以使任務棧清理包括根activity在內的任何activity對象。

    這裡也有另一種方法來使activity對象從任務棧中被移除。若Intent對象包含FLAG_ACTIVITY_CLEAR_TOP標誌,並且在目標任務棧中已經存在了用於處理這個Intent對象的activity類型的一個執行個體,那麼在任務棧中這個執行個體之上的所有activity執行個體會被移除。從而用於處理這個Intent對象的activity類型的那個執行個體會位於任務棧的棧頂,並用來處理那個Intent對象。若那個匹合的activity類型的啟動模式是“standard”,則這個已經存在於任務棧中的匹合的activity類型的執行個體也會被移除,並且一個新的此類型activity的執行個體被建立並壓棧來處理這個Intent對象。

    FLAG_ACTIVITY_CLEAR_TOP這個標誌經常和FLAG_ACTIVITY_NEW_TASK標誌結合使用,這樣結合使用的意思是在另一個任務棧中定位已經存在的匹合的activity類型的執行個體,並且讓此執行個體位於棧頂。

4.啟動任務棧

    通過將一個activity類型的intent-filter的動作設定為“android.intent.action.MAIN”,類別設定為“android.intent.category.LAUNCHER”可以使這個activity執行個體稱為一個任務棧的入口。擁有這種類型的intent-filter的activity類型的圖表和名字也會顯示在application launcher中。

    第二個能力是很重要的:使用者必須能夠使一個任務棧切換到後台,也可以隨時將其切換到前台。出於這個原因,使activity在啟動時新開任務棧的啟動模式(即“singleTask”和“singleInstance”模式)只應該被利用在擁有擁有“android.intent.action.MAIN”動作和“android.intent.category.LAUNCHER”類別的intent-filter的activity類型上。

    類似的限制同樣體現在FLAG_ACTIVITY_NEW_TASK標誌上。如果這個標誌使一個activity開始了一個新的任務棧,並且使用者點擊“HOME”鍵將其切換到了後台,則必須有某種方式使使用者可以重新將那個任務棧切換到前台。一些執行個體(比如通知管理器),總是在外部的任務棧中開啟一個activity,而不是其自身的任務棧,所以它們總是將FLAG_ACTIVITY_NEW_TASK標誌放入Intent對象中,並將Intent對象傳入startActivity()方法中。

    對於在某些情況下,你不希望使用者能夠返回到某一個activity,那麼可以通過設定<activity>標籤的“finishOnTaskLaunch”屬性為“true”來實現。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.