page.title=工作和返回堆疊 parent.title=Activity parent.link=activities.html @jd:body <div id="qv-wrapper"> <div id="qv"> <h2>本文件內容</h2> <ol> <li><a href="#ActivityState">儲存 Activity 狀態</a></li></li> <li><a href="#ManagingTasks">管理工作</a> <ol> <li><a href="#TaskLaunchModes">定義啟動模式</a></li> <li><a href="#Affinities">處理親和性</a></li> <li><a href="#Clearing">清除返回堆疊</a></li> <li><a href="#Starting">開始工作</a></li> </ol> </li> </ol> <h2>文章</h2> <ol> <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html"> Android 的多工作業方式 </a></li> </ol> <h2>另請參閱</h2> <ol> <li><a href="{@docRoot}design/patterns/navigation.html">Android 設計:導覽 </a></li> <li><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>} 宣示說明元素 </a></li> <li><a href="{@docRoot}guide/components/recents.html">總覽畫面</a></li> </ol> </div> </div> <p>一個應用程式通常包含多個 <a href="{@docRoot}guide/components/activities.html">Activity</a>。每個 Activity 應根據使用者可執行的特定動作類型加以設計,且要能啟動其他 Activity。 例如,電子郵件應用程式可能會有一個可顯示新訊息清單的 Activity。 當使用者選擇一則訊息,會開啟新的 Activity 以檢視該訊息。</p> <p>Activity 甚至可啟動裝置上其他應用程式的 Activity。例如,如果您的應用程式想要傳送一封電子郵件訊息,您可以定義一個意圖以執行「傳送」動作並包含一些資料,像是電子郵件地址和訊息。 其他應用程式中宣告處理此意圖類型的 Activity 就會開啟。 在這種情況下,意圖就是要傳送電子郵件,因此電子郵件應用程式會啟動「撰寫」Activity (如果有多個 Activity 支援相同的意圖,則系統會讓使用者選擇要使用的 Activity)。 電子郵件傳送後,您的 Activity 就會繼續,並將電子郵件 Activity 視為您應用程式的一部分。 雖然 Activity 可能來自不同的應用程式,但 Android 會將兩個 Activity 放在相同的工作中,以維護使用者體驗的流暢性。 <em></em></p> <p>工作是執行特定工作時,與使用者互動的 Activity 集合。 Activity 會在堆疊 (返回堆疊<em></em>) 中依照每個 Activity 開啟的順序加以排列。 </p> <!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED <div class="sidebox-wrapper"> <div class="sidebox"> <h3>Adding fragments to a task's back stack</h3> <p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example, suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the other being a layout to display an item from the list (fragment B). When the user selects an item from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be desireable for the user to navigate back to reveal fragment B, using the <em>Back</em> button.</p> <p>In order to add fragment B to the back stack so that this is possible, you must call {@link android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment C.</p> <p>For more information about using fragments and adding them to the back stack, see the {@link android.app.Fragment} class documentation.</p> </div> </div> --> <p>裝置主螢幕是大多數工作開始的地方。當使用者輕觸應用程式啟動組件上的某個圖示 (或主螢幕上的捷徑 ) 時,應用程式工作會移到前景。 如果應用程式沒有工作 (最近未使用應用程式),則會建立新的工作,且該應用程式的「主要」Activity 會以堆疊中的根 Activity 形式開啟。 </p> <p>當目前的 Activity 啟動另一個 Activity 時,會將新的 Activity 推到堆疊的頂端並取得焦點。 之前的 Activity 會留在堆疊中,但已停止。Activity 停止後,系統會保留其使用者介面的目前狀態。 當使用者按下 [返回] 按鈕<em></em>,會將目前的 Activity 從堆疊頂端推出 (Activity 已終結),並繼續進行之前的 Activity (還原其 UI 之前的狀態)。 堆疊中的 Activity 不會重新整理,只會從堆疊推入和推出 — 由目前 Activity 啟動時推入堆疊,而當使用者使用 [返回] 按鈕離開時推出堆疊。<em></em> 因此,返回堆疊會以「後進先出」的物件結構進行運作。 圖 1 透過時間軸將此行為視覺化,以時間軸顯示 Activity 間的進度以及每個時間點的目前返回堆疊。 </p> <img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" /> <p class="img-caption"><strong>圖 1.</strong>顯示工作中每個新 Activity 如何將項目新增到返回堆疊。 當使用者按下 [返回] 按鈕,目前的 Activity 將會終結,而之前的 Activity 則會繼續進行。<em></em> </p> <p>如果使用者持續按下 [返回]<em></em>,則會持續推出堆疊中的每個 Activity 以顯示之前的 Activity,直到使用者返回主螢幕 (或到工作開始時執行的 Activity)。 當堆疊中的 Activity 全部移除後,工作將不再存在。</p> <div class="figure" style="width:287px"> <img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p class="img-caption"><strong>圖 2.</strong>兩個工作:工作 B 在前景收到使用者互動,而工作 A 在背景等待繼續。 </p> </div> <div class="figure" style="width:215px"> <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p class="img-caption"><strong>圖 3.</strong>單一 Activity 會具現化很多次。</p> </div> <p>工作是一個緊密結合的單位,當使用者開始新的工作時可以移到「背景」,或透過 [首頁] 按鈕前往主螢幕。<em></em> 在背景時,工作中的所有 Activity 都會停止,但該工作的返回堆疊會保留下來 — 該工作純粹失去焦點,由另一個工作取而代之,如圖 2 所示。 之後,工作可以返回「前景」,讓使用者繼續未完成的工作。 例如,假設目前的工作 (工作 A) 的堆疊中有三個 Activity — 兩個位於目前的 Activity 下。 使用者按下 [首頁] 按鈕,<em></em>然後從應用程式啟動新的應用程式。 當主螢幕出現時,工作 A 會移到背景。 新的應用程式啟動時,系統會啟動該應用程式的工作 (工作 B),該應用程式會有自己的 Activity 堆疊。 與該應用程式互動之後,使用者會再次回到首頁,並選取原來啟動工作 A 的應用程式。現在,工作 A 移到了前景 — 堆疊中的三個 Activity 全部保持不變,而堆疊中最頂端的 Activity 則會繼續進行。 此時,使用者也能切換回工作 B,前往首頁並選取啟動該工作的應用程式圖示 (或從<a href="{@docRoot}guide/components/recents.html">總覽畫面</a>選取應用程式工作)。這是在 Android 執行多工作業的範例。 </p> <p class="note"><strong>注意:</strong>背景可以一次執行多個工作。 不過,如果使用者同時執行多個背景工作,系統可能會開始終結背景 Activity 以復原記憶體,導致 Activity 狀態遺失。 請參閱下列有關 <a href="#ActivityState">Activity 狀態</a>的章節。 </p> <p>由於返回堆疊中的 Activity 不會重新整理,如果您的應用程式允許使用者從一個以上的 Activity 中啟動特定 Activity,則會建立該 Activity 的新執行個體並推入堆疊 (而不會將 Activity 任何之前的執行個體移到最頂端)。 因此,您應用程式中的一個 Activity 可能會具現化很多次 (甚至來自不同的工作),如圖 3 所示。 也因為這樣,如果使用者使用 [返回] 按鈕瀏覽之前的資訊,Activity 的每個執行個體會依開啟的順序顯示<em></em> (每個會有自己的 UI 狀態)。 不過,如果您不希望 Activity 具現化一次以上,則可以修改這個行為。 如需詳細步驟,請參閱下文的<a href="#ManagingTasks">管理工作</a>。</p> <p>摘要說明 Activity 和工作的預設行為:</p> <ul> <li>當 Activity A 啟動 Activity B,Activity A 會停止,但系統會保留其狀態(例如捲軸位置和輸入表單的文字)。 如果使用者在 Activity B 按下 [返回] 按鈕,<em></em>Activity A 的狀態會復原並繼續執行。 </li> <li>當使用者按下 [首頁] 按鈕離開工作,<em></em>目前的 Activity 會停止且其工作會移到背景。 系統會保留工作中所有 Activity 的狀態。如果使用者稍後選取啟動工作的啟動組件圖示繼續執行工作,工作會移到前景並在堆疊頂端繼續執行 Activity。 </li> <li>如果使用者按下 [返回] 按鈕<em></em>,會將目前的 Activity 從堆疊推出並終結。 堆疊中之前的 Activity 會繼續進行。Activity 終結後,系統將不會保留 Activity 的狀態。 <em></em></li> <li>Activity 可以具現化很多次,即使來自其他工作也一樣。</li> </ul> <div class="note design"> <p><strong>導覽設計</strong></p> <p>如需應用程式導覽如何在 Android 運作的詳細資訊,請參閱 Android 設計的<a href="{@docRoot}design/patterns/navigation.html">導覽</a>指南。</p> </div> <h2 id="ActivityState">儲存 Activity 狀態</h2> <p>如上所述,系統的預設行為會在 Activity 停止時保留 Activity 的狀態。 如此一來,當使用者瀏覽之前的 Activity 時,其使用者介面的顯示方式將與離開時一樣。 不過,您可以 — 也<strong>應該</strong> — 使用回呼方法主動保留 Activity 的狀態,以防止 Activity 遭到終結且必須重新建立的情況。 </p> <p>如果系統停止您其中一個 Activity (例如,當新的 Activity 開始或工作移到背景),當系統需要復原系統記憶體時,可能會完全終結該 Activity。 發生這種情況時,與 Activity 狀態相關的資訊都將遺失。如果發生這種情況,系統仍然知道該 Activity 位於返回堆疊中,但是當 Activity 移到堆疊頂端時,系統必須重新建立該 Activity (而不是繼續執行)。 如果不想讓使用者的工作遺失,您應該在 Activity 中實作 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} 回呼方法,主動保留該工作。 </p> <p>如需儲存 Activity 狀態的詳細資訊,請參閱 <a href="{@docRoot}guide/components/activities.html#SavingActivityState">Activity</a> 文件。 </p> <h2 id="ManagingTasks">管理工作</h2> <p>如上所述,Android 管理工作和返回堆疊的方式 — 將連續啟動的所有 Activity 放在相同的工作及「後進先出」堆疊中 — 對大多數應用程式而言非常好用,而且您不需擔心 Activity 與工作關聯的方式或它們如何存在於返回堆疊中。 不過,您也許會想中斷一般的行為。 您或許會希望應用程式的 Activity 可以在啟動時開始一個新的工作 (而不是放入目前的工作中);或者當您啟動一個 Activity 時,您可能會想使用其現有的執行個體 (而不是在返回堆疊頂端建立新的執行個體);又或者當使用者離開工作時,您想要清除返回堆疊中的所有 Activity,只留下根 Activity。 </p> <p>如要執行這些工作及更多工作,您可以使用 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 宣示說明元素中的屬性,以及您傳送到 {@link android.app.Activity#startActivity startActivity()} 之意圖中的旗標。 </p> <p>就這個情況而言,您可以使用的主要 <a href="{@docRoot}guide/topics/manifest/activity-element.html"> {@code <activity>}</a> 屬性包括:</p> <ul class="nolist"> <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff"> {@code taskAffinity}</a></li> <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode"> {@code launchMode}</a></li> <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> {@code allowTaskReparenting}</a></li> <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear"> {@code clearTaskOnLaunch}</a></li> <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> {@code alwaysRetainTaskState}</a></li> <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish"> {@code finishOnTaskLaunch}</a></li> </ul> <p>而您可以使用的主要意圖旗標包括:</p> <ul class="nolist"> <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li> <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li> <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li> </ul> <p>在以下各節中,您將瞭解如何使用這些宣示說明屬性和意圖旗標,定義 Activity 與工作關聯的方式以及它們在返回堆疊中的行為。 </p> <p>同時,還會分開討論工作與 Activity 如何在總覽畫面表示和進行管理。 請參閱<a href="{@docRoot}guide/components/recents.html">總覽畫面</a>以取得詳細資訊。 一般而言,您應該允許系統定義如何在總覽畫面中呈現工作與 Activity,而且不需要修改此行為。 </p> <p class="caution"><strong>注意:</strong>大多數應用程式不應中斷 Activity 和工作的預設行為: 如果您判斷修改 Activity 的預設行為是必要的,請謹慎小心並記得測試啟動期間 Activity 的可用性,以及使用 [返回] 按鈕從其他 Activity 和工作瀏覽到此 Activity 的情況。請記得測試可能會與使用者預期的行為衝突的瀏覽行為。<em></em> </p> <h3 id="TaskLaunchModes">定義啟動模式</h3> <p>啟動模式可讓您定義 Activity 的新執行個體與目前工作關聯的方式。 您可用兩種方法定義不同的啟動模式:</p> <ul class="nolist"> <li><a href="#ManifestForTasks">使用宣示說明檔案</a> <p>當您在宣示說明檔案中宣告 Activity 時,您可以指定 Activity 啟動時該如何與工作關聯。 </li> <li><a href="#IntentFlagsForTasks">使用意圖旗標</a> <p>當您呼叫 {@link android.app.Activity#startActivity startActivity()} 時,您可以在 {@link android.content.Intent} 包含一個旗標,宣告新 Activity 應如何 (或是否) 與目前的工作關聯。 </p></li> </ul> <p>因此,如果 Activity A 啟動 Activity B,Activity B 可以在其宣示說明中定義它應如何與目前的工作 (如果有) 關聯,而且 Activity A 也能要求 Activity B 應如何與目前的工作關聯。 如果這兩個 Activity 皆定義 Activity B 應如何與工作關聯,相較於 Activity B 的要求 (如宣示說明中所定義),會優先採用 Activity A 的要求 (如意圖中所定義)。 </p> <p class="note"><strong>注意:</strong>某些宣示說明檔案中提供的啟動模式可能沒有對應的意圖旗標,同樣地,某些意圖旗標提供的啟動模式無法在宣示說明中定義。 </p> <h4 id="ManifestForTasks">使用宣示說明檔案</h4> <p>當您在宣示說明檔案中宣告 Activity 時,您可以使用 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 元素的 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 屬性,指定 Activity 應如何與工作關聯。 </p> <p><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 屬性可指定應如何將 Activity 啟動至工作內的指示。 您可以為 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code> 屬性指定四種不同的啟動模式: </p> <dl> <dt>{@code "standard"} (預設模式)</dt> <dd>預設。系統在啟動 Activity 的工作中建立新的執行個體,並將意圖路由至該處。 Activity 可以具現化很多次,每個執行個體可屬於不同的工作,而且一個工作可以有多個執行個體。 </dd> <dt>{@code "singleTop"}</dt> <dd>如果 Activity 的執行個體已經出現在目前工作的頂端,系統會透過呼叫其 {@link android.app.Activity#onNewIntent onNewIntent()} 方法,將意圖路由至該執行個體,而不是建立新的 Activity 執行個體。 Activity 可以具現化很多次,每個執行個體可屬於不同的工作,而且一個工作可以有多個執行個體 (但僅限於返回堆疊頂端的 Activity 不是現有的 Activity 執行個體時<em></em>)。 <p>例如,假設工作的返回堆疊包含根 Activity A 及 Activity B、C 及在最頂端的 D (堆疊為 A-B-C-D;D 在最頂端)。 類型 D Activity 的意圖抵達。 如果 D 有預設的 {@code "standard"} 啟動模式,則會啟動新的類別執行個體,且堆疊會變成 A-B-C-D-D。不過,如果 D 啟動模式為 {@code "singleTop"},D 的現有執行個體會透過 {@link android.app.Activity#onNewIntent onNewIntent()} 接收意圖,這是因為它位於堆疊的最頂端 — 堆疊會維持 A-B-C-D。不過,如果類型 B Activity 的意圖抵達,則 B 的新執行個體會新增到堆疊中,即使其啟動模式為 {@code "singleTop"} 也是如此。 </p> <p class="note"><strong>注意:</strong>建立新的 Activity 執行個體之後,使用者可按下 [返回]<em></em> 按鈕,返回之前的 Activity。 但是,如果處理新意圖的是現有的 Activity 執行個體,則使用者無法按下 [返回]<em></em> 按鈕回到新意圖抵達 {@link android.app.Activity#onNewIntent onNewIntent()} 之前的 Activity 狀態。 </p> </dd> <dt>{@code "singleTask"}</dt> <dd>系統會建立新的工作並在新工作的根目錄將 Activity 具現化。不過,如果 Activity 的執行個體已經出現在其他工作中,系統會透過呼叫其 {@link android.app.Activity#onNewIntent onNewIntent()} 方法,將意圖路由至現有的執行個體,而不是建立新的執行個體。 一次只能有一個 Activity 執行個體。 <p class="note"><strong>注意:</strong>雖然 Activity 是在新工作中啟動,使用者仍可使用 [返回] 按鈕返回之前的 Activity。 <em></em></p></dd> <dt>{@code "singleInstance"}。</dt> <dd>與 {@code "singleTask"} 一樣,差別在於系統不會將任何其他 Activity 啟動至保留執行個體的工作中。 Activity 一律是其工作的唯一成員;使用此項目啟動的任何 Activity 會在個別的工作中開啟。 </dd> </dl> <p>另外一個例子,Android 瀏覽器應用程式宣告網頁瀏覽器 Activity 應永遠在自己的工作中開啟 — 透過在 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 元素指定 {@code singleTask} 啟動模式。 這表示如果您的應用程式發出開啟 Android 瀏覽器的意圖,其 Activity 不會與您的應用程式放在同一個工作中。<em></em> 而是會為瀏覽器啟動新的工作,或者如果瀏覽器已經有工作在背景執行,會將該工作帶出來處理新的意圖。 </p> <p>無論 Activity 在新工作啟動或與啟動該 Activity 之 Activity 的相同工作中啟動,使用者都能使用 [返回] 按鈕返回之前的 Activity。<em></em> 不過,如果您啟動指定 {@code singleTask} 啟動模式的 Activity,如果該 Activity 的執行個體存在於背景工作中,則該工作會整個移到前景。 此時,返回堆疊現在包含已帶出且位於堆疊頂端之工作的所有 Activity。 圖 4 說明這種類型的情況。</p> <img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" /> <p class="img-caption"><strong>圖 4.</strong>顯示含有啟動模式 "singleTask" 的 Activity 如何新增到返回堆疊。 如果 Activity 已經是背景工作的一部份且有自己的返回堆疊,則整個返回堆疊都會帶出來,位於目前工作的最頂端。 </p> <p>如要進一步瞭解如何使用宣示說明檔案中的啟動模式,請參閱 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 元素,其中會有 {@code launchMode} 屬性和可接受值的詳細說明。 </p> <p class="note"><strong>注意:</strong>您使用 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 屬性指定的 Activity 行為可被啟動 Activity 之意圖所含的旗標所覆寫,如下一節所述。 </p> <h4 id="#IntentFlagsForTasks">使用意圖旗標</h4> <p>啟動 Activity 時,您可以在傳送到 {@link android.app.Activity#startActivity startActivity()} 的意圖中包含旗標,以修改 Activity 及其工作的預設關聯。 您可以用來修改預設行為的旗標包括: </p> <p> <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt> <dd>在新工作中啟動 Activity。如果工作已為您目前啟動的 Activity 執行,該工作會移到前景並復原至上個狀態,而且 Activity 會在 {@link android.app.Activity#onNewIntent onNewIntent()} 收到新的意圖。 <p>這會產生與 {@code "singleTask"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 值相同的行為,如上節所述。 </p></dd> <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt> <dd>如果現在正在啟動的 Activity 是目前的 Activity (位於返回堆疊的頂端),則現有執行個體會收到 {@link android.app.Activity#onNewIntent onNewIntent()} 呼叫,而不會建立新的 Activity 執行個體。 <p>這會產生與 {@code "singleTop"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 值相同的行為,如上節所述。 </p></dd> <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt> <dd>如果正在啟動的 Activity 已在目前的工作中執行,則不會啟動新的 Activity 執行個體,而是會終結位於其上方的所有其他 Activity,且此意圖會透過 {@link android.app.Activity#onNewIntent onNewIntent()} 傳送到繼續執行的 Activity 執行個體 (現在位於頂端)。 <p>沒有任何 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 屬性值可以產生此行為。 </p> <p>{@code FLAG_ACTIVITY_CLEAR_TOP} 最常與 {@code FLAG_ACTIVITY_NEW_TASK} 搭配使用。 一起使用時,這些旗標可以找出位於其他工作中的現有 Activity,然後將它放置於可以回應意圖的地方。 </p> <p class="note"><strong>注意:</strong>如果指定 Activity 的啟動模式為 {@code "standard"},它也會從堆疊中移除,改為啟動新的執行個體處理傳入的意圖。 這是因為當啟動模式為 {@code "standard"} 時,一律會為新的意圖建立新的執行個體。 </p> </dd> </dl> <h3 id="Affinities">處理親和性</h3> <p>親和性<em></em>可指出 Activity 偏好屬於哪個工作。根據預設,相同應用程式的所有 Activity 間互相都有親和性。 因此,根據預設,相同應用程式的所有 Activity 都偏好位於相同的工作。 不過,您可以修改 Activity 的預設親和性。 不同應用程式中定義的 Activity 可以共用親和性,或者相同應用程式中定義的 Activity 可以指派不同的工作親和性。 </p> <p>您可以使用 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 元素的 <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 屬性修改任何指定 Activity 的親和性。 </p> <p><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 屬性使用字串值,但必須與 <a href="{@docRoot}guide/topics/manifest/manifest-element.html"> {@code <manifest>}</a> 元素中宣告的預設封裝名稱不同,因為系統使用該名稱來識別應用程式的預設工作親和性。 </p> <p>在兩種情況下會用到親和性:</p> <ul> <li>當啟動 Activity 的意圖包含 {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} 旗標。 <p>根據預設,新的 Activity 會啟動至 Activity (名為 {@link android.app.Activity#startActivity startActivity()}) 的工作中。 系統會將它推入至與呼叫端相同的返回堆疊。 不過,如果傳送至 {@link android.app.Activity#startActivity startActivity()} 的意圖包含 {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} 旗標,則系統會找尋不同的工作來放置新的 Activity。 這通常是新工作。 不過,它不一定要是新工作。如果現有工作中有與新 Activity 相同的親和性,Activity 會啟動至該工作中。 如果沒有,會開始新的工作。</p> <p>如果此旗標導致 Activity 開始新的工作,而使用者按 [首頁] 按鈕離開它,必須要有方法可以讓使用者回來瀏覽這個工作。<em></em> 有些實體 (例如,通知管理員) 總是從外部工作開始 Activity,從來不使用自己的工作,因此他們都會將 {@code FLAG_ACTIVITY_NEW_TASK} 放入傳送到 {@link android.app.Activity#startActivity startActivity()} 的意圖。 如果您的 Activity 可以由外部實體呼叫且可能使用此旗標,記得要提供使用者獨立的方法回到啟動的工作,例如,透過啟動組件圖示 (工作的根 Activity 有一個 {@link android.content.Intent#CATEGORY_LAUNCHER} 意圖篩選器;請參閱下方的<a href="#Starting">開始工作</a>)。 </p> </li> <li>當 Activity 的<a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> {@code allowTaskReparenting}</a> 屬性設為 {@code "true"}。 <p>在這種情況下,當工作移到前景時,Activity 可以從其啟動的工作移到與其有親和性的工作。 </p> <p>例如,假設將報告所選城市天氣狀況的 Activity 定義為旅遊應用程式的一部份。 它與相同應用程式中的其他 Activity 有相同的親和性 (預設的應用程式親和性),而且它允許與此屬性重設父代。 當您的其中一個 Activity 開始氣象報告程式 Activity,它一開始屬於與您 Activity 相同的工作。 不過,當旅遊應用程式工作移到前景,氣象報告程式 Activity 就會重新指派給該工作,並在其中顯示。 </p> </li> </ul> <p class="note"><strong>提示:</strong>如果從使用者的角度來看 {@code .apk} 檔案包含一個以上的「應用程式」,您可能會想要使用 <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 屬性對與每個「應用程式」關聯的 Activity 指派不同的親和性。 </p> <h3 id="Clearing">清除返回堆疊</h3> <p>如果使用者離開工作一段很長的時間,系統會清除根 Activity 以外所有 Activity 的工作 。當使用者再次回到工作,只會復原根 Activity。 系統會有這樣的行為是因為在一段很長的時間後,使用者很可能會放棄他們之前在做的工作,並回到工作開始其他新的工作。 </p> <p>您可以使用下列一些 Activity 屬性來修改這個行為: </p> <dl> <dt><code><a href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code> </dt> <dd>如果這項屬性在工作的根 Activity 中設為 {@code "true"},則剛描述的預設行為不會發生。 即使過了很長的一段時間,工作仍然會在堆疊保留所有的 Activity。 </dd> <dt><code><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt> <dd>如果這項屬性在工作的根 Activity 中設為 {@code "true"},則剛描述的預設行為不會發生。 即使過了很長的一段時間,工作仍然會在堆疊保留所有的 Activity。 換句話說,它與 <a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> {@code alwaysRetainTaskState}</a> 相反。即便使用者只離開工作一小段時間,使用者還是會回到工作的起始狀態。 </dd> <dt><code><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code> </dt> <dd>這項屬性與 <a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a> 相似,但它在單一 Activity 上作業,而不是在整個工作。 它也會導致任何 Activity 離開,包含根 Activity。 如果設成 {@code "true"},Activity 只會在目前的工作階段留在此工作中。 如果使用者離開後再回到工作,該工作將不再存在。 </dd> </dl> <h3 id="Starting">開始工作</h3> <p>您可以給予 Activity 一個意圖篩選器,將 {@code "android.intent.action.MAIN"} 設定為指定的動作, {@code "android.intent.category.LAUNCHER"} 設定為指定的類別,以便將該 Activity 設定為工作的進入點。 例如:</p> <pre> <activity ... > <intent-filter ... > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> ... </activity> </pre> <p>這類意圖篩選器可在應用程式啟動組件顯示 Activity 的圖示和標籤,讓使用者啟動 Activity 並回到 Activity 啟動後任何時間建立的工作。 </p> <p>第二項功能很重要:使用者必須能夠在離開工作後,使用此 Activity 啟動組件回到此工作。 由於這個原因,兩個將 Activity 標示為一律啟動工作的<a href="#LaunchModes">啟動模式</a> {@code "singleTask"} 和 {@code "singleInstance"},應只能在 Activity 有 {@link android.content.Intent#ACTION_MAIN} 和 {@link android.content.Intent#CATEGORY_LAUNCHER} 篩選器時才能使用。 例如,試想如果缺少篩選器會發生什麼情況: 意圖會啟動 {@code "singleTask"} Activity、起始新工作,然後使用者會花一些時間在該工作進行作業。 之後,使用者按下 [首頁]<em></em> 按鈕。 此工作現在會傳送到背景而且不會顯示。現在,使用者沒有辦法回到工作,這是因為應用程式啟動組件沒有代表此工作的項目。 </p> <p>在您不希望使用者返回 Activity 的情況下,將 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 元素的 <a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code finishOnTaskLaunch}</a> 設定為 {@code "true"} (請參閱<a href="#Clearing">清除堆疊</a>)。 </p> <p>如要進一步瞭解工作和 Activity 在總覽畫面中的顯示及管理方式,請參閱<a href="{@docRoot}guide/components/recents.html">總覽畫面</a>。 </p> <!-- <h2>Beginner's Path</h2> <p>For more information about how to use intents to activate other application components and publish the intents to which your components respond, continue with the <b><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a></b> document.</p> -->