Android下Affinities和Task

來源:互聯網
上載者:User

最近幾天在看官方文檔時,一直卡在Affinities和Task這一環節,主要原因是在閱讀英文的時候,不像其餘的章節那樣順暢,以至於無法正確地理解Affinities,於是google到一文章,通讀了一遍才終於明白,不過具體怎麼應用,我還不清楚,等以後在寫程式的時候遇到這個再進一步深入吧。

源文連結:http://appmem.com/archives/405

本文參考了官方Dev Guide文檔,簡單介紹Android下的affinities和任務(task)。

1、Activity和Task

task就好像是能包含很多activity的棧。 預設情況下,一個activity啟動另外一個activity時,兩個activity是放在同一個task棧中的,第二個activity壓入第一個activity所在的task棧。當使用者按下返回鍵時,第二個activity從棧中彈出,第一個activity又在當前螢幕顯示。這樣,從使用者角度來看,這兩個activity就好像是屬於同一個應用程式的,即使第二個activity是屬於另外一個應用程式的。當然,這是指預設情況下。 task棧包含的是activity的對象。如果一個activity有多個執行個體在運行,那麼棧中儲存的是每個執行個體的實體。棧中的activity不會重新排列,只有彈出和壓入操作。 一個task中的所有activity都以整體的形式移動。整個task可以被移到前台或後台。打個比方,當前的task包含4個activity–當前activity下面有3個activity。當使用者按下HOME鍵返回到程式啟動器(application launcher)後,選擇了一個新的應用程式(事實上是一個新的task),當前的task就被轉移到後台,新的task中的根activity將被顯示在螢幕上。過了一段時間,使用者按返回鍵回到了程式啟動器介面,選擇了之前啟動並執行程式(之前的task)。那個task,仍然包含著4個activity。當使用者再次按下返回鍵時,螢幕不會顯示之前留下的那個activity(之前的task的根activity),而顯示當前activity從task棧中移出後棧頂的那個activity。 剛剛描述的行為是預設的activity和task的行為。有很多方法能夠改變這種行為。activity和task之間的聯絡,以及task中的activity的行為可以通過intent中的標記以及在manifest中的<activity>元素的屬性控制。其中,主要的Intent標記有:

l FLAG_ACTIVITY_NEW_TASK

l FLAG_ACTIVITY_CLEAR_TOP

l FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

l FLAG_ACTIVITY_SINGLE_TOP

主要的<activity>屬性有:

l taskAffinity

l launchMode

l allowTaskReparenting

l clearTaskOnLaunch

l alwaysRetainTaskState

l finishOnTaskLaunch

預設情況下,一個應用程式中的所有activity都有一個affinity–這讓它們屬於同一個task。然而,每個activity可以通過<activity>中的taskAffinity屬性設定單獨的affinity。不同應用程式中的activity可以共用同一個affinity,同一個應用程式中的不同activity也可以設定成不同的affinity。affinity屬性在2種情況下起作用:當啟動activity的Intent對象包含FLAG_ACTIVITY_NEW_TASK標記,或當activity的allowTaskReparenting被設定成true。

l FLAG_ACTIVITY_NEW_TASK標記

當傳遞給startActivity()的Intent對象包含FLAG_ACTIVITY_NEW_TASK標記時,系統會為需要啟動的activity尋找與當前activity不同的task。如果要啟動的activity的affinity屬性與當前所有的task的affinity屬性都不相同,系統會建立一個帶那個affinity屬性的task,並將要啟動的activity壓到建立的task棧中;否則將activity壓入那個affinity屬性相同的棧中。

l allowTaskReparenting屬性

如果一個activity的allowTaskReparenting屬性為true,那麼它可以從一個task(TASK1)移到另外一個有相同affinity的task(TASK2)中(TASK2帶到前台時)。

如果一個.apk檔案從使用者角度來看包含了多個“應用程式”,你可能需要對那些activity賦不同的affinity值。

2、運行模式

activity的launchMode屬性可以有四種值:

l “standard” (預設)

l “singleTop“

l “singleTask“

l “singleInstance“

這4種模式可以按4種分類來區分,以下假設位於task1中的activity1啟動activity2:

模式\分類

包容activity2的task

一個activity是否允許有多個執行個體

activity是否允許有其它activity共存於一個task

對於新的intent,是否總是執行個體化activity對象

standard

如果不包含FLAG_ACTIVITY_NEW_TASK標記,則activity2放入task1,否則按前面講述的規則為activity2選擇task

可被多次執行個體化,同一個task的不同的執行個體可位於不同的task中,每個task也可包含多個執行個體

允許

是的。當接收到新的intent時,總是會產生新的activity對象。

singleTop

同standard

同standard

允許

已存在的activity對象,如果位於目標task的棧頂,則該activity被重用,如果它不位於棧頂,則會執行個體化新的activity對象

singleTask

將activity2放到task1棧底

不能有多個執行個體。由於該模式下activity總是位於棧頂,所以actvity在同一個裝置裡至多隻有一個執行個體

允許。singleTask模式的activity總是位於棧底位置。目標activity執行個體已存在時,如果該執行個體剛好位於task棧頂,則接收intent,否則到來的intent將會被丟棄,但該可以響應該intent的那個activity所在的task將會被移到前台。

 

singleInstance

同singleTask

同singleTask

不允許與其它activity共存於一個task。如果activity1的運行在該模式下,則activity2一定與activity1位於不同的task

 

對於新到的intent,如果是由新建立的activity對象來接收,則使用者可以通過返回鍵回到之前的activity;如果是由已存在的activity來接收,則使用者無法通過返回鍵返回到接收intent之前的狀態。

3、清空棧

當使用者長時間離開task(當前task被轉移到後台)時,系統會清除task中棧底activity外的所有activity。這樣,當使用者返回到task時,只留下那個task最初始的activity了。

這是預設的情況,<activity>中有些屬性可以改變這種行為。

l alwaysRetainTaskState屬性

如果棧底activity的這個屬性被設定為true,剛剛描述的情況就不會發生。task中的所有activity將被長時間儲存。

l clearTaskOnLaunch屬性

如果棧底activity的這個屬性被設定為true,一旦使用者離開task,則task棧中的activity將被清空到只剩下棧底activity。這種情況剛好與alwaysRetainTaskState相反。即使使用者只是短暫地離開,task也會返回到初始狀態(只剩下棧底acitivty)。

l finishOnTaskLaunch屬性

這個屬性與clearTaskOnLaunch相似,但它只對單獨的activity操作,而不是整個task。它可以結束任何activity,包括棧底的activity。當它設定為true時,當前的activity只在當前會話期間作為task的一部分存在,當使用者退出activity再返回時,它將不存在。

另外還有一種方法能將activity強行從stack中移出。如果intent對象包含FLAG_ACTIVITY_CLEAR_TOP標記,當目標task中已存在與接收該intent對象的activity類型相同的activity執行個體存在時,所有位於該activity對象上面的activity將被清空,這樣接收該intent的activity就位於棧頂,可以響應到來的intent對象。如果目標activity的運行模式為standard,則目標activtiy也會被清空。因為當運行模式為standard時,總會建立新的activity對象來接收到來的intent對象。

FLAG_ACTIVITY_CLEAR_TOP標記常常和FLAG_ACTIVITY_NEW_TASK一起使用。用2個標記可以定位已存在的activity並讓它處於可以響應intent的位置。

4、啟動任務(Task)

Intent filter中有”android.intent.action.MAIN” action和”android.intent.category.LAUNCHER” category的activity將被標記為task的入口。帶有這兩個標記的activity將會顯示在應用程式啟動器(application launcher)中。

第二個比較重要的點是,使用者必須能夠離開task並在之後返回。因為這個原因,singleTask和singleInstance這兩種運行模式只能應用於含有MAIN和LAUNCHER過濾器的activity。打個比方,如果不包含帶MAIN和LAUNCHER過濾器,某個activity運行了一個singleTask模式的activity,初始化了一個新的task,當使用者按下HOME鍵時,那個activity就被主畫面“擋住”了,使用者再也無法返回到那個activity。

類似的情況在FLAG_ACTIVITY_NEW_TASK標記上也會出現。如果這個標記會建立一個task,當使用者按下HOME鍵時,必須有一種方式能夠讓使用者返回到那個activity。有些東西(比如notification manager)總是要求在外部task中啟動activity,在傳遞給startActivity的intent中總是包含FLAG_ACTIVITY_NEW_TASK標記。

對於那種不希望使用者離開之後再返回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.