翻譯SDK文檔Tasks and Back Stack

、術語解釋 


        1.task:一系列activity的集合,這些activity就可以看成是一個任務。 
        2.back stack:一系列activity的存儲結構,因其遵循後進先出的原則,所以我個人譯爲“回退堆棧”,但本文仍沿用英文代表其原義。 

     二、相關文檔

      1.http://chirs1012f.iteye.com/blog/986987

                  2.http://www.iteye.com/topic/1111875

    3.http://winuxxan.blog.51cto.com/2779763/504047

    一個應用程序通常包含多個Activity,每一個Activity都有它自己的功能並且可以啓動其他的Activity,例如:一個郵件的應用程序可能有一個Activity現實它的最新郵件,當用戶選擇一個郵件的時候啓動一個新的Activity來顯示這個電子郵件。


    一個Activity甚至可以打開在這個設備上的不同應用程序的Activity,例如,如果您的應用程序要發送一封電子郵件,你可以定義一個執行“發送”的行動,其中包括一些數據,如電子郵件地址和郵件的內容。一個可以從其它程序打開的Activity要再Manifest聲明啓動它的Intent的種類。在這種情況下,你是要發送一封電子郵件,那麼電子郵件應用程序的撰寫Activity將被啓動(如果系統註冊了多個同樣的Intent,用戶可以選擇使用哪一個)當電子郵件發送,您的應用程序中的Activity將可見,這樣看起來似乎發送郵件是您應用程序的一部分,即使Activity可以從不同的應用啓動,Android的保持這種無縫的用戶體驗,這兩個Activity在同一個Task裏面。


一個Task是收集用戶執行某些工作時,互動的Activity。Activity被安排在一個stack (“back stack”),其中的順序是Activity打開的順序。


設備的Home Screen 是大多數Task的起始位置。當用戶觸摸圖標在Main Menu(或在主屏幕上的快捷方式),該應用程序的Task會被推到前臺。如果沒有該應用程序的Task(應用程序尚未最近使用)存在,則創建一個新的Task,應用程序的"main"Activity將作爲該Task的根。


如果當前顯示的Activity打開另外一個Activity,那麼這個新打開的Activity將會被放置到Task的頂部,並且獲取焦點,上一個activity仍然在堆棧中,但是已經被stop,但是系統會保持這個Activity的當前狀態。當用戶按下BACK鍵,當前的Activity是從堆棧的頂部移除並且銷燬,上一個Activity將會被顯示(恢復以前保存的狀態)。Activity所在的堆棧永遠都不會重新排列,只有進棧和出棧,用戶啓動一個Activity時進棧,Back時出棧。因此Back stack準守“先進後出”的原則。下圖介紹了大概的流程:




圖1。一個代表性的每個Activity如何增加到Task。當用戶按下BACK鍵,當前活動被刪除並銷燬,並恢復到以前的activity。


如果你繼續點擊Back鍵,那麼當前顯示的Activity都將被移除,並且顯示前一個Activity,直到用戶返回到Home Screen,當所有的Activity都從Task中移除,這個Task也將被銷燬。


一個Task是一個被凝聚的單元,他可以被整體移動到後臺,當用戶開啓了一個新的Task或者用戶通過Home鍵返回到Home Screen的時候。當它進入後臺,它所包含的所有的Activity都將Stop,但是Task仍然保持不變,它只是失去了焦點讓給了另外一個Task,如圖2所示



圖2:兩個Task:Task,A在後臺,等待恢復,而Task B在前臺接收用戶交互。


用戶可以讓一個Task回到前臺,假如:Task A有3個Activity在堆棧裏面,2個在下面,用戶按下Home鍵,然後啓動另外一個應用程序,Task a進入後臺,系統爲新的應用程序建立一個它自己的堆棧 Task B,用戶和Task B 交互後再選擇A,此時Task A完好無損,並且恢復到頂部的Activity,此時用戶還可以繼續選擇B,這是android一個多應用的簡單的例子。


注:多個任務可以在後臺,但是如果系統資源不足,則會殺死一些後臺Activity,有時可能會造成數據的丟失。


因爲Activity在Back stack中是不可以被重新排序的,if your application allows users to start a particular activity from more than one activity,新的Activity實例將被創建,並且加入到Stack中(而不是把上一個實例移動到stack的最頂端),因此,在您的應用程序中的一個Activity可能被實例化多次(甚至是從不同的Task),如圖3所示 。





圖3。一個Activity被實例化多次。


if the user navigates backward using the BACK key, each instance of the activity is revealed in the order they were opened (each with their own UI state).但是,您可以修改此行爲,如果你不想把一個Activity多次實例化。這將是接下來討論的內容


總結默認Task:

1、當Activity A 開啓Activity B ,A被Stop,但是系統保留了他的狀態(如滾動條的位置,輸入的文本),如果用戶在B按下返回鍵那麼A將被恢復

2、當用戶通過HOME鍵離開Task,當前的Activity將被Stop並且Task進入後臺,系統會保留這個Task中所有Activity的狀態,如果用戶通過選擇Launche上的ICON恢復了這個Task,這個Task將回到前臺並且顯示它頂部的那一個Activity。

3、如果用戶按下Back鍵,當前的Activity將從Task從移除,並且銷燬,下一個Activity將被恢復,被銷燬的Activity不會被保存狀態。

4、Activity可以被多次實例化,甚至在其他的Task中。



保存Activity狀態:

正如上面說的,系統默認保存被Stop的Activity的狀態,這樣,用戶通過Back鍵將返回到上一個Activity並且是他離開時的界面,However, you can—and should —proactively retain the state of your activities using callback methods, in case the activity is destroyed and must be recreated.


當系統資源部足時會殺死一些Activity,所以您可以通過onSaveInstanceState()來保存你的狀態。

For more information about how to save your activity state, see the Activities document.


管理Task:

Android的Task 和Back stack管理正如上面所說,所有的Activity在成功啓動之後都是“先進後出”的原則,對於大多數的應用程序來說,您不用擔心您的Activity在Task和Back stack中是怎麼退出和進入的。但是,您可能有特殊的需求需要更改這樣的行爲。也許您希望您應用程序中的一個Activity在創建的時候進入一個新的Task(不是當前的Task),或者您想使用一個已經存在的實例(而不是創建一個新的實例在back stack的頂部),或者您希望當用戶離開您的Task時清楚除了根Activity之外的所有Activity.


您可以做這些事情只要您配置Manifest中<activity>標籤的屬性和您再調用startActivity()時Intent的屬性。


在Activity的屬性中  您主要可以使用

在Intent的屬性中 您主要可以使用

在接下來的內容中 您將看到如何使用這些,這些和Task和Back stack的關係。

注意:大多數的應用程序 不需要更改這些行爲。如果您真的需要使用,請您謹慎測試,他可能會發生您預料之外的事情。


定義launchMode

Launch modes允許您定義如何創建一個新的Activity在當前的Task中。您可以定義launchMode有兩種方式:

1、使用manifest:當你聲明一個Activity在manifest文件中,您可以指定Activity應如何與Task相關聯,當它啓動時。

2、使用Intent flags:當您調用startActivity()時,您可以通過setFlags()來聲明怎麼(是否)創建一個Activity在當前的Task中。


因此如果Activity A啓動 Activity B ,B在manifest中定義瞭如何在task中創建新的實例,A也可以要求B如何加載,如果這兩種都有定義,那麼A請求的優先級(在Intent中定義)將高於B所定義的優先級(在manifest中定義)。


Note: Some the launch modes available in the manifest are not available as flags for an intent and, likewise, some launch modes available as flags for an intent cannot be defined in the manifest.

以下翻譯不知道是否正確

注:一些launchMode,在manifest中有在Intent中沒有,同樣在Intent中有的可能在manifet中沒有。



使用manifest文件

manifest文件中聲明一個Activity時,可以指定Activity應如何與Task相關聯 ,通過設置<activity> 元素的launchMode屬性

launchMode屬性指定一個Activity如何被加入到Task中 。有四種不同的Mode,可以 分配 給launchMode屬性:


"standard" (默認模式)

當它開始的時候系統都會爲它在Task中創建一個新的實例。Activity可以多次實例化,每個實例都可以屬於不同的Task,一個Task可以有多個實例。

“singleTop”

如果一個Activity已經存在於當前Task的頂部,那麼系統將通過onNewInten()調用到該實例,而不是啓動一個新的實例,Activity可以多次實例化,每個實例都可以屬於不同的Task,一個Task可以有多個實例(但僅限於這個Task的頂部不存在這個Activity纔會去創建新的)。

例如:假設一個Task的Back stack是 a-b-c-d,a在底部,d在頂部,這時候一個Intent要start d這個Activity,如果d的launchMode是standard”那麼系統將創建一個新的實例,現在的堆棧就變成a-b-c-d-d,但是如果d的launchMode是“singleTop”的,那麼已經存在的d會通過onNewIntent來處理這種行爲,那麼之後的堆棧仍然是a-b-c-d,因爲d在這個堆棧的頂部,但是如果一個Intent要啓動b,那麼系統將會創建一個b的新實例,因爲b不在堆棧的頂部。


    * 注意,當創建一個新的activity實例來處理一個新的行爲時,用戶總是能夠通過按下BACK按鍵退回到前面的狀態(前一個activity)。但是當一個已經存在的activity實例處理一個新的行爲時,用戶不能通過按下BACK按鍵退回到前面的狀態。 (沒有測試具體情況)

"singleTask"

系統將創建一個新的Task和新的Activity在Task的底部 。但是如果一個Activity已經存在Task中,會調用他的onNewIntent()方法,而不是創建一個新的實例,在一段時間內只能有一個實例存在。

注意:雖然是在一個新的Task中開始的,但是用戶點擊返回鍵仍然會返回到前一個Activity.


“singleInstance” 

singleTask基本上一樣,但是singleInstance的Task中不能再加入其他的Activity,這個實例只有一個。


另外的一個例子,瀏覽器的應用程序聲明他的瀏覽網頁的Activity始終打開在她自己的Task中(通過設置launchMode=“singleTask”),這意味着,如果你的程序需要打開ANdroid的瀏覽器,他的Activity和您的應用程序並沒有在一個Task中。或者創建一個新的Task或者使用已經存在的實例接受您的意圖。


不管一個Activity的開始是在一個新的Task還是在同樣的Task中,用戶點擊返回鍵都會返回到他瀏覽的上一個Activity。不過,如果你從你的Task(A)啓動了一個launchMode=“singleTask”的Activity的話,也許這個Activity已經有一個實例在後臺並且有它自己的Task(B),

在這種情況下,如果Task B要接收一個新的Intent的話,BACK鍵會首先TaskB 中的Activity直到返回到Task A的最頂端。




使用Intent flags

有以下flags:

FLAG_ACTIVITY_NEW_TASK

創建一個新的Task爲這個Activity ,

他將產生和“singleTask”一樣的行爲。


FLAG_ACTIVITY_SINGLE_TOP

這將產生相同的行爲“singleTop”


FLAG_ACTIVITY_CLEAR_TOP

如果啓動的Activity已經運行在當前的Task中,那麼他將銷燬他上面所有的Activity而不是去創建一個新的Activity。














以下內容轉載自:http://lydia-ylh.iteye.com/blog/1100050

    * 哪個任務存放着activity,用來對行爲進行響應。對“standard”和“singleTop”模式來說,這個任務是產生行爲(並且調用 startActivity())的那個——除非行爲對象包含了 FLAG_ACTIVITY_NEW_TASK標記。在這種情況下,像前面那節Affinities and new tasks 描述的一樣,將會選擇一個不同的任務。 
    * 它們是否可以有多個實例。”standard”和“singleTop”類型的activity可以被實例化多次。它們可以屬於多個任務,一個特定的任務也可以擁有同一個activity的多個實例。 
    * 作爲比較”singleTask”和”singleInstance”類型的activity只限定有一個實例。因爲這些activity是任務的根。這個限制意味着,在設備上不能同時有超過一個任務的實例。 
    * 是否能有其他的activity在它所在的任務中。”singleInstance”類型的activity是它所在任務中唯一的 activity。如果它啓動了其他的activity,不管那個activity的啓動模式如何,它都會加載到一個不同的任務中——好像行爲對象中的 FLAG_ACTIVITY_NEW_TASK標記。在其他的方面,”singleInstance”和”singleTask”模式是相同的。 
    * 其他三種模式運行任務中有多個activity。”singleTask”總是任務中的根activity,但是它可以啓動其他的activity並分配到它所在的任務中。”standard”和”singleTop”類型的activity可以出現在任務中的任何地方。 
    * 是否啓動一個新的實例來處理一個新的行爲。對默認的”standard”模式來說,對於每一個行爲都會創建一個新的實例來響應。每個實例只處理一個行爲。對於”singleTop”模式,如果一個已經存在的實例位於目標任務activity棧的棧頂,那麼他將被重用來處理這個行爲。如果它不在棧頂,它將不會被重用,而是爲行爲創建一個新的實例,並壓入棧中。 
    * 例如,假設,一個任務的activity棧由根activity A和 B,C,D從上到下按這樣的順序組成,所以這個棧就是A-B-C-D。一個行爲指向類型爲D的activity。如果D是默認的”standard”加載模式,一個新的實例會被啓動,棧現在就是這樣A-B-C-D-D。但是,如果D的加載模式是”singleTop”,已經存在的實例會用來處理這個行爲 (因爲它在棧的頂端)並且棧中還應該是A-B-C-D。 
    * 在前面提到,”singleTask”和”singleInstance”類型的activity最多隻有一個實例,所以他們的實例應該會處理每個新的行爲。”singleInstance”類型的activity總是在棧的頂端(因爲他是任務中唯一的一個activity),所以總是能夠適當的處理行爲。然而,”singleTask”類型的activity也許會有其他的activity在它的上面。如果是這樣的話,那就不能處理這個行爲,這個行爲被丟棄。(即使這個行爲被丟棄了,它的到來也會導致那些應該保留不變任務顯示到前臺來)。 
    * 當一個activity被要求處理一個新的行爲時,行爲對象會通過調用activity的 onNewIntent() 方法傳遞進來(最初啓動activity的行爲可以通過調用getIntent()方法獲得)。 
    * 注意,當創建一個新的activity實例來處理一個新的行爲時,用戶總是能夠通過按下BACK按鍵退回到前面的狀態(前一個activity)。但是當一個已經存在的activity實例處理一個新的行爲時,用戶不能通過按下BACK按鍵退回到前面的狀態。 

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