1page.title=工作和返回堆疊 2parent.title=Activity 3parent.link=activities.html 4@jd:body 5 6<div id="qv-wrapper"> 7<div id="qv"> 8 9<h2>本文件內容</h2> 10<ol> 11<li><a href="#ActivityState">儲存 Activity 狀態</a></li></li> 12<li><a href="#ManagingTasks">管理工作</a> 13 <ol> 14 <li><a href="#TaskLaunchModes">定義啟動模式</a></li> 15 <li><a href="#Affinities">處理親和性</a></li> 16 <li><a href="#Clearing">清除返回堆疊</a></li> 17 <li><a href="#Starting">開始工作</a></li> 18 </ol> 19</li> 20</ol> 21 22<h2>文章</h2> 23<ol> 24 <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html"> Android 的多工作業方式 25</a></li> 26</ol> 27 28<h2>另請參閱</h2> 29<ol> 30 <li><a href="{@docRoot}design/patterns/navigation.html">Android 設計:導覽 31</a></li> 32 <li><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>} 宣示說明元素 33</a></li> 34 <li><a href="{@docRoot}guide/components/recents.html">總覽畫面</a></li> 35</ol> 36</div> 37</div> 38 39 40<p>一個應用程式通常包含多個 <a href="{@docRoot}guide/components/activities.html">Activity</a>。每個 Activity 應根據使用者可執行的特定動作類型加以設計,且要能啟動其他 Activity。 41 42例如,電子郵件應用程式可能會有一個可顯示新訊息清單的 Activity。 43當使用者選擇一則訊息,會開啟新的 Activity 以檢視該訊息。</p> 44 45<p>Activity 甚至可啟動裝置上其他應用程式的 Activity。例如,如果您的應用程式想要傳送一封電子郵件訊息,您可以定義一個意圖以執行「傳送」動作並包含一些資料,像是電子郵件地址和訊息。 46 47其他應用程式中宣告處理此意圖類型的 Activity 就會開啟。 48在這種情況下,意圖就是要傳送電子郵件,因此電子郵件應用程式會啟動「撰寫」Activity (如果有多個 Activity 支援相同的意圖,則系統會讓使用者選擇要使用的 Activity)。 49 50電子郵件傳送後,您的 Activity 就會繼續,並將電子郵件 Activity 視為您應用程式的一部分。 51雖然 Activity 可能來自不同的應用程式,但 Android 會將兩個 Activity 放在相同的工作中,以維護使用者體驗的流暢性。 52 53<em></em></p> 54 55<p>工作是執行特定工作時,與使用者互動的 Activity 集合。 56Activity 會在堆疊 (返回堆疊<em></em>) 中依照每個 Activity 開啟的順序加以排列。 57</p> 58 59<!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED 60<div class="sidebox-wrapper"> 61<div class="sidebox"> 62<h3>Adding fragments to a task's back stack</h3> 63 64<p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example, 65suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the 66other being a layout to display an item from the list (fragment B). When the user selects an item 67from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be 68desireable for the user to navigate back to reveal fragment B, using the <em>Back</em> button.</p> 69<p>In order to add fragment B to the back stack so that this is possible, you must call {@link 70android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link 71android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment 72C.</p> 73<p>For more information about using fragments and adding them to the back stack, see the {@link 74android.app.Fragment} class documentation.</p> 75 76</div> 77</div> 78--> 79 80<p>裝置主螢幕是大多數工作開始的地方。當使用者輕觸應用程式啟動組件上的某個圖示 (或主螢幕上的捷徑 ) 時,應用程式工作會移到前景。 81 82如果應用程式沒有工作 (最近未使用應用程式),則會建立新的工作,且該應用程式的「主要」Activity 會以堆疊中的根 Activity 形式開啟。 83 84</p> 85 86<p>當目前的 Activity 啟動另一個 Activity 時,會將新的 Activity 推到堆疊的頂端並取得焦點。 87之前的 Activity 會留在堆疊中,但已停止。Activity 停止後,系統會保留其使用者介面的目前狀態。 88當使用者按下 [返回] 按鈕<em></em>,會將目前的 Activity 從堆疊頂端推出 (Activity 已終結),並繼續進行之前的 Activity (還原其 UI 之前的狀態)。 89 90 91堆疊中的 Activity 不會重新整理,只會從堆疊推入和推出 — 由目前 Activity 啟動時推入堆疊,而當使用者使用 [返回] 按鈕離開時推出堆疊。<em></em> 92 93因此,返回堆疊會以「後進先出」的物件結構進行運作。 94 95圖 1 透過時間軸將此行為視覺化,以時間軸顯示 Activity 間的進度以及每個時間點的目前返回堆疊。 96 97</p> 98 99<img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" /> 100<p class="img-caption"><strong>圖 1.</strong>顯示工作中每個新 Activity 如何將項目新增到返回堆疊。 101當使用者按下 [返回] 按鈕,目前的 Activity 將會終結,而之前的 Activity 則會繼續進行。<em></em> 102 103</p> 104 105 106<p>如果使用者持續按下 [返回]<em></em>,則會持續推出堆疊中的每個 Activity 以顯示之前的 Activity,直到使用者返回主螢幕 (或到工作開始時執行的 Activity)。 107 108 109當堆疊中的 Activity 全部移除後,工作將不再存在。</p> 110 111<div class="figure" style="width:287px"> 112<img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p 113class="img-caption"><strong>圖 2.</strong>兩個工作:工作 B 在前景收到使用者互動,而工作 A 在背景等待繼續。 114</p> 115</div> 116<div class="figure" style="width:215px"> 117 <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p 118class="img-caption"><strong>圖 3.</strong>單一 Activity 會具現化很多次。</p> 119</div> 120 121<p>工作是一個緊密結合的單位,當使用者開始新的工作時可以移到「背景」,或透過 [首頁] 按鈕前往主螢幕。<em></em> 122在背景時,工作中的所有 Activity 都會停止,但該工作的返回堆疊會保留下來 — 該工作純粹失去焦點,由另一個工作取而代之,如圖 2 所示。 123 124 125之後,工作可以返回「前景」,讓使用者繼續未完成的工作。 126例如,假設目前的工作 (工作 A) 的堆疊中有三個 Activity — 兩個位於目前的 Activity 下。 127使用者按下 [首頁] 按鈕,<em></em>然後從應用程式啟動新的應用程式。 128 129當主螢幕出現時,工作 A 會移到背景。 130新的應用程式啟動時,系統會啟動該應用程式的工作 (工作 B),該應用程式會有自己的 Activity 堆疊。 131與該應用程式互動之後,使用者會再次回到首頁,並選取原來啟動工作 A 的應用程式。現在,工作 A 移到了前景 — 堆疊中的三個 Activity 全部保持不變,而堆疊中最頂端的 Activity 則會繼續進行。 132 133 134 135此時,使用者也能切換回工作 B,前往首頁並選取啟動該工作的應用程式圖示 (或從<a href="{@docRoot}guide/components/recents.html">總覽畫面</a>選取應用程式工作)。這是在 Android 執行多工作業的範例。 136 137 138 139</p> 140 141<p class="note"><strong>注意:</strong>背景可以一次執行多個工作。 142不過,如果使用者同時執行多個背景工作,系統可能會開始終結背景 Activity 以復原記憶體,導致 Activity 狀態遺失。 143請參閱下列有關 <a href="#ActivityState">Activity 狀態</a>的章節。 144</p> 145 146<p>由於返回堆疊中的 Activity 不會重新整理,如果您的應用程式允許使用者從一個以上的 Activity 中啟動特定 Activity,則會建立該 Activity 的新執行個體並推入堆疊 (而不會將 Activity 任何之前的執行個體移到最頂端)。 147 148 149因此,您應用程式中的一個 Activity 可能會具現化很多次 (甚至來自不同的工作),如圖 3 所示。 150也因為這樣,如果使用者使用 [返回] 按鈕瀏覽之前的資訊,Activity 的每個執行個體會依開啟的順序顯示<em></em> (每個會有自己的 UI 狀態)。 151 152 153不過,如果您不希望 Activity 具現化一次以上,則可以修改這個行為。 154如需詳細步驟,請參閱下文的<a href="#ManagingTasks">管理工作</a>。</p> 155 156 157<p>摘要說明 Activity 和工作的預設行為:</p> 158 159<ul> 160 <li>當 Activity A 啟動 Activity B,Activity A 會停止,但系統會保留其狀態(例如捲軸位置和輸入表單的文字)。 161 162如果使用者在 Activity B 按下 [返回] 按鈕,<em></em>Activity A 的狀態會復原並繼續執行。 163</li> 164 <li>當使用者按下 [首頁] 按鈕離開工作,<em></em>目前的 Activity 會停止且其工作會移到背景。 165 166系統會保留工作中所有 Activity 的狀態。如果使用者稍後選取啟動工作的啟動組件圖示繼續執行工作,工作會移到前景並在堆疊頂端繼續執行 Activity。 167 168</li> 169 <li>如果使用者按下 [返回] 按鈕<em></em>,會將目前的 Activity 從堆疊推出並終結。 170 171堆疊中之前的 Activity 會繼續進行。Activity 終結後,系統將不會保留 Activity 的狀態。 172<em></em></li> 173 <li>Activity 可以具現化很多次,即使來自其他工作也一樣。</li> 174</ul> 175 176 177<div class="note design"> 178<p><strong>導覽設計</strong></p> 179 <p>如需應用程式導覽如何在 Android 運作的詳細資訊,請參閱 Android 設計的<a href="{@docRoot}design/patterns/navigation.html">導覽</a>指南。</p> 180</div> 181 182 183<h2 id="ActivityState">儲存 Activity 狀態</h2> 184 185<p>如上所述,系統的預設行為會在 Activity 停止時保留 Activity 的狀態。 186如此一來,當使用者瀏覽之前的 Activity 時,其使用者介面的顯示方式將與離開時一樣。 187不過,您可以 — 也<strong>應該</strong> — 使用回呼方法主動保留 Activity 的狀態,以防止 Activity 遭到終結且必須重新建立的情況。 188 189</p> 190 191<p>如果系統停止您其中一個 Activity (例如,當新的 Activity 開始或工作移到背景),當系統需要復原系統記憶體時,可能會完全終結該 Activity。 192 193發生這種情況時,與 Activity 狀態相關的資訊都將遺失。如果發生這種情況,系統仍然知道該 Activity 位於返回堆疊中,但是當 Activity 移到堆疊頂端時,系統必須重新建立該 Activity (而不是繼續執行)。 194 195 196如果不想讓使用者的工作遺失,您應該在 Activity 中實作 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} 回呼方法,主動保留該工作。 197 198 199</p> 200 201<p>如需儲存 Activity 狀態的詳細資訊,請參閱 <a href="{@docRoot}guide/components/activities.html#SavingActivityState">Activity</a> 文件。 202</p> 203 204 205 206<h2 id="ManagingTasks">管理工作</h2> 207 208<p>如上所述,Android 管理工作和返回堆疊的方式 — 將連續啟動的所有 Activity 放在相同的工作及「後進先出」堆疊中 — 對大多數應用程式而言非常好用,而且您不需擔心 Activity 與工作關聯的方式或它們如何存在於返回堆疊中。 209 210 211不過,您也許會想中斷一般的行為。 212您或許會希望應用程式的 Activity 可以在啟動時開始一個新的工作 (而不是放入目前的工作中);或者當您啟動一個 Activity 時,您可能會想使用其現有的執行個體 (而不是在返回堆疊頂端建立新的執行個體);又或者當使用者離開工作時,您想要清除返回堆疊中的所有 Activity,只留下根 Activity。 213 214 215 216</p> 217 218<p>如要執行這些工作及更多工作,您可以使用 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 宣示說明元素中的屬性,以及您傳送到 {@link android.app.Activity#startActivity startActivity()} 之意圖中的旗標。 219 220 221</p> 222 223<p>就這個情況而言,您可以使用的主要 <a href="{@docRoot}guide/topics/manifest/activity-element.html"> 224{@code <activity>}</a> 屬性包括:</p> 225 226<ul class="nolist"> 227 <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff"> 228 {@code taskAffinity}</a></li> 229 <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode"> 230 {@code launchMode}</a></li> 231 <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> 232 {@code allowTaskReparenting}</a></li> 233 <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear"> 234 {@code clearTaskOnLaunch}</a></li> 235 <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> 236 {@code alwaysRetainTaskState}</a></li> 237 <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish"> 238 {@code finishOnTaskLaunch}</a></li> 239</ul> 240 241<p>而您可以使用的主要意圖旗標包括:</p> 242 243<ul class="nolist"> 244 <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li> 245 <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li> 246 <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li> 247</ul> 248 249<p>在以下各節中,您將瞭解如何使用這些宣示說明屬性和意圖旗標,定義 Activity 與工作關聯的方式以及它們在返回堆疊中的行為。 250</p> 251 252<p>同時,還會分開討論工作與 Activity 如何在總覽畫面表示和進行管理。 253請參閱<a href="{@docRoot}guide/components/recents.html">總覽畫面</a>以取得詳細資訊。 254一般而言,您應該允許系統定義如何在總覽畫面中呈現工作與 Activity,而且不需要修改此行為。 255</p> 256 257<p class="caution"><strong>注意:</strong>大多數應用程式不應中斷 Activity 和工作的預設行為: 258如果您判斷修改 Activity 的預設行為是必要的,請謹慎小心並記得測試啟動期間 Activity 的可用性,以及使用 [返回] 按鈕從其他 Activity 和工作瀏覽到此 Activity 的情況。請記得測試可能會與使用者預期的行為衝突的瀏覽行為。<em></em> 259 260 261</p> 262 263 264<h3 id="TaskLaunchModes">定義啟動模式</h3> 265 266<p>啟動模式可讓您定義 Activity 的新執行個體與目前工作關聯的方式。 267您可用兩種方法定義不同的啟動模式:</p> 268<ul class="nolist"> 269 <li><a href="#ManifestForTasks">使用宣示說明檔案</a> 270 <p>當您在宣示說明檔案中宣告 Activity 時,您可以指定 Activity 啟動時該如何與工作關聯。 271</li> 272 <li><a href="#IntentFlagsForTasks">使用意圖旗標</a> 273 <p>當您呼叫 {@link android.app.Activity#startActivity startActivity()} 時,您可以在 {@link android.content.Intent} 包含一個旗標,宣告新 Activity 應如何 (或是否) 與目前的工作關聯。 274 275</p></li> 276</ul> 277 278<p>因此,如果 Activity A 啟動 Activity B,Activity B 可以在其宣示說明中定義它應如何與目前的工作 (如果有) 關聯,而且 Activity A 也能要求 Activity B 應如何與目前的工作關聯。 279 280如果這兩個 Activity 皆定義 Activity B 應如何與工作關聯,相較於 Activity B 的要求 (如宣示說明中所定義),會優先採用 Activity A 的要求 (如意圖中所定義)。 281 282</p> 283 284<p class="note"><strong>注意:</strong>某些宣示說明檔案中提供的啟動模式可能沒有對應的意圖旗標,同樣地,某些意圖旗標提供的啟動模式無法在宣示說明中定義。 285 286</p> 287 288 289<h4 id="ManifestForTasks">使用宣示說明檔案</h4> 290 291<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 292launchMode}</a> 屬性,指定 Activity 應如何與工作關聯。 293 294</p> 295 296<p><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code 297launchMode}</a> 屬性可指定應如何將 Activity 啟動至工作內的指示。 298您可以為 299<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code> 屬性指定四種不同的啟動模式: 300</p> 301 302<dl> 303<dt>{@code "standard"} (預設模式)</dt> 304 <dd>預設。系統在啟動 Activity 的工作中建立新的執行個體,並將意圖路由至該處。 305Activity 可以具現化很多次,每個執行個體可屬於不同的工作,而且一個工作可以有多個執行個體。 306</dd> 307<dt>{@code "singleTop"}</dt> 308 <dd>如果 Activity 的執行個體已經出現在目前工作的頂端,系統會透過呼叫其 {@link 309android.app.Activity#onNewIntent onNewIntent()} 方法,將意圖路由至該執行個體,而不是建立新的 Activity 執行個體。 310 311Activity 可以具現化很多次,每個執行個體可屬於不同的工作,而且一個工作可以有多個執行個體 (但僅限於返回堆疊頂端的 Activity 不是現有的 Activity 執行個體時<em></em>)。 312 313 314 <p>例如,假設工作的返回堆疊包含根 Activity A 及 Activity B、C 及在最頂端的 D (堆疊為 A-B-C-D;D 在最頂端)。 315類型 D Activity 的意圖抵達。 316如果 D 有預設的 {@code "standard"} 啟動模式,則會啟動新的類別執行個體,且堆疊會變成 A-B-C-D-D。不過,如果 D 啟動模式為 {@code "singleTop"},D 的現有執行個體會透過 {@link 317android.app.Activity#onNewIntent onNewIntent()} 接收意圖,這是因為它位於堆疊的最頂端 — 堆疊會維持 A-B-C-D。不過,如果類型 B Activity 的意圖抵達,則 B 的新執行個體會新增到堆疊中,即使其啟動模式為 {@code "singleTop"} 也是如此。 318 319 320 321</p> 322 <p class="note"><strong>注意:</strong>建立新的 Activity 執行個體之後,使用者可按下 [返回]<em></em> 按鈕,返回之前的 Activity。 323但是,如果處理新意圖的是現有的 Activity 執行個體,則使用者無法按下 [返回]<em></em> 按鈕回到新意圖抵達 {@link android.app.Activity#onNewIntent 324onNewIntent()} 之前的 Activity 狀態。 325 326 327 328</p> 329</dd> 330 331<dt>{@code "singleTask"}</dt> 332 <dd>系統會建立新的工作並在新工作的根目錄將 Activity 具現化。不過,如果 Activity 的執行個體已經出現在其他工作中,系統會透過呼叫其 {@link 333android.app.Activity#onNewIntent onNewIntent()} 方法,將意圖路由至現有的執行個體,而不是建立新的執行個體。 334 335一次只能有一個 Activity 執行個體。 336 337 <p class="note"><strong>注意:</strong>雖然 Activity 是在新工作中啟動,使用者仍可使用 [返回] 按鈕返回之前的 Activity。 338<em></em></p></dd> 339<dt>{@code "singleInstance"}。</dt> 340 <dd>與 {@code "singleTask"} 一樣,差別在於系統不會將任何其他 Activity 啟動至保留執行個體的工作中。 341Activity 一律是其工作的唯一成員;使用此項目啟動的任何 Activity 會在個別的工作中開啟。 342</dd> 343</dl> 344 345 346<p>另外一個例子,Android 瀏覽器應用程式宣告網頁瀏覽器 Activity 應永遠在自己的工作中開啟 — 透過在 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 元素指定 {@code singleTask} 啟動模式。 347這表示如果您的應用程式發出開啟 Android 瀏覽器的意圖,其 Activity 不會與您的應用程式放在同一個工作中。<em></em> 348 349 350而是會為瀏覽器啟動新的工作,或者如果瀏覽器已經有工作在背景執行,會將該工作帶出來處理新的意圖。 351 352</p> 353 354<p>無論 Activity 在新工作啟動或與啟動該 Activity 之 Activity 的相同工作中啟動,使用者都能使用 [返回] 按鈕返回之前的 Activity。<em></em> 355不過,如果您啟動指定 {@code singleTask} 啟動模式的 Activity,如果該 Activity 的執行個體存在於背景工作中,則該工作會整個移到前景。 356 357此時,返回堆疊現在包含已帶出且位於堆疊頂端之工作的所有 Activity。 358 359圖 4 說明這種類型的情況。</p> 360 361<img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" /> 362<p class="img-caption"><strong>圖 4.</strong>顯示含有啟動模式 "singleTask" 的 Activity 如何新增到返回堆疊。 363如果 Activity 已經是背景工作的一部份且有自己的返回堆疊,則整個返回堆疊都會帶出來,位於目前工作的最頂端。 364 365</p> 366 367<p>如要進一步瞭解如何使用宣示說明檔案中的啟動模式,請參閱 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 元素,其中會有 {@code launchMode} 屬性和可接受值的詳細說明。 368 369 370</p> 371 372<p class="note"><strong>注意:</strong>您使用 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 屬性指定的 Activity 行為可被啟動 Activity 之意圖所含的旗標所覆寫,如下一節所述。 373 374</p> 375 376 377 378<h4 id="#IntentFlagsForTasks">使用意圖旗標</h4> 379 380<p>啟動 Activity 時,您可以在傳送到 {@link 381android.app.Activity#startActivity startActivity()} 的意圖中包含旗標,以修改 Activity 及其工作的預設關聯。 382您可以用來修改預設行為的旗標包括: 383</p> 384 385<p> 386 <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt> 387 <dd>在新工作中啟動 Activity。如果工作已為您目前啟動的 Activity 執行,該工作會移到前景並復原至上個狀態,而且 Activity 會在 {@link android.app.Activity#onNewIntent onNewIntent()} 收到新的意圖。 388 389 390 <p>這會產生與 {@code "singleTask"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 值相同的行為,如上節所述。 391</p></dd> 392 <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt> 393 <dd>如果現在正在啟動的 Activity 是目前的 Activity (位於返回堆疊的頂端),則現有執行個體會收到 {@link android.app.Activity#onNewIntent onNewIntent()} 呼叫,而不會建立新的 Activity 執行個體。 394 395 396 <p>這會產生與 {@code "singleTop"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 值相同的行為,如上節所述。 397</p></dd> 398 <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt> 399 <dd>如果正在啟動的 Activity 已在目前的工作中執行,則不會啟動新的 Activity 執行個體,而是會終結位於其上方的所有其他 Activity,且此意圖會透過 {@link android.app.Activity#onNewIntent onNewIntent()} 傳送到繼續執行的 Activity 執行個體 (現在位於頂端)。 400 401 402 403 <p>沒有任何 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 屬性值可以產生此行為。 404</p> 405 <p>{@code FLAG_ACTIVITY_CLEAR_TOP} 最常與 {@code FLAG_ACTIVITY_NEW_TASK} 搭配使用。 406一起使用時,這些旗標可以找出位於其他工作中的現有 Activity,然後將它放置於可以回應意圖的地方。 407 408 </p> 409 <p class="note"><strong>注意:</strong>如果指定 Activity 的啟動模式為 {@code "standard"},它也會從堆疊中移除,改為啟動新的執行個體處理傳入的意圖。 410 411 412這是因為當啟動模式為 {@code "standard"} 時,一律會為新的意圖建立新的執行個體。 413 </p> 414</dd> 415</dl> 416 417 418 419 420 421<h3 id="Affinities">處理親和性</h3> 422 423<p>親和性<em></em>可指出 Activity 偏好屬於哪個工作。根據預設,相同應用程式的所有 Activity 間互相都有親和性。 424因此,根據預設,相同應用程式的所有 Activity 都偏好位於相同的工作。 425不過,您可以修改 Activity 的預設親和性。 426不同應用程式中定義的 Activity 可以共用親和性,或者相同應用程式中定義的 Activity 可以指派不同的工作親和性。 427 428</p> 429 430<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 的親和性。 431 432</p> 433 434<p><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 屬性使用字串值,但必須與 <a href="{@docRoot}guide/topics/manifest/manifest-element.html"> 435{@code <manifest>}</a> 元素中宣告的預設封裝名稱不同,因為系統使用該名稱來識別應用程式的預設工作親和性。 436 437 438 439</p> 440 441<p>在兩種情況下會用到親和性:</p> 442<ul> 443 <li>當啟動 Activity 的意圖包含 444{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} 旗標。 445 446 447<p>根據預設,新的 Activity 會啟動至 Activity (名為 {@link android.app.Activity#startActivity startActivity()}) 的工作中。 448系統會將它推入至與呼叫端相同的返回堆疊。 449不過,如果傳送至 450{@link android.app.Activity#startActivity startActivity()} 的意圖包含 {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} 旗標,則系統會找尋不同的工作來放置新的 Activity。 451 452這通常是新工作。 453不過,它不一定要是新工作。如果現有工作中有與新 Activity 相同的親和性,Activity 會啟動至該工作中。 454如果沒有,會開始新的工作。</p> 455 456<p>如果此旗標導致 Activity 開始新的工作,而使用者按 [首頁] 按鈕離開它,必須要有方法可以讓使用者回來瀏覽這個工作。<em></em> 457 458有些實體 (例如,通知管理員) 總是從外部工作開始 Activity,從來不使用自己的工作,因此他們都會將 {@code FLAG_ACTIVITY_NEW_TASK} 放入傳送到 459{@link android.app.Activity#startActivity startActivity()} 的意圖。 460 461如果您的 Activity 可以由外部實體呼叫且可能使用此旗標,記得要提供使用者獨立的方法回到啟動的工作,例如,透過啟動組件圖示 (工作的根 Activity 有一個 {@link android.content.Intent#CATEGORY_LAUNCHER} 意圖篩選器;請參閱下方的<a href="#Starting">開始工作</a>)。 462 463 464 465</p> 466</li> 467 468 <li>當 Activity 的<a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> 469{@code allowTaskReparenting}</a> 屬性設為 {@code "true"}。 470 <p>在這種情況下,當工作移到前景時,Activity 可以從其啟動的工作移到與其有親和性的工作。 471</p> 472 <p>例如,假設將報告所選城市天氣狀況的 Activity 定義為旅遊應用程式的一部份。 473它與相同應用程式中的其他 Activity 有相同的親和性 (預設的應用程式親和性),而且它允許與此屬性重設父代。 474當您的其中一個 Activity 開始氣象報告程式 Activity,它一開始屬於與您 Activity 相同的工作。 475 476不過,當旅遊應用程式工作移到前景,氣象報告程式 Activity 就會重新指派給該工作,並在其中顯示。 477</p> 478</li> 479</ul> 480 481<p class="note"><strong>提示:</strong>如果從使用者的角度來看 {@code .apk} 檔案包含一個以上的「應用程式」,您可能會想要使用 <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 屬性對與每個「應用程式」關聯的 Activity 指派不同的親和性。 482 483</p> 484 485 486 487<h3 id="Clearing">清除返回堆疊</h3> 488 489<p>如果使用者離開工作一段很長的時間,系統會清除根 Activity 以外所有 Activity 的工作 490。當使用者再次回到工作,只會復原根 Activity。 491系統會有這樣的行為是因為在一段很長的時間後,使用者很可能會放棄他們之前在做的工作,並回到工作開始其他新的工作。 492 </p> 493 494<p>您可以使用下列一些 Activity 屬性來修改這個行為: </p> 495 496<dl> 497<dt><code><a 498href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code> 499</dt> 500<dd>如果這項屬性在工作的根 Activity 中設為 {@code "true"},則剛描述的預設行為不會發生。 501即使過了很長的一段時間,工作仍然會在堆疊保留所有的 Activity。 502</dd> 503 504<dt><code><a 505href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt> 506<dd>如果這項屬性在工作的根 Activity 中設為 {@code "true"},則剛描述的預設行為不會發生。 507即使過了很長的一段時間,工作仍然會在堆疊保留所有的 Activity。 508換句話說,它與 509<a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> 510{@code alwaysRetainTaskState}</a> 相反。即便使用者只離開工作一小段時間,使用者還是會回到工作的起始狀態。 511</dd> 512 513<dt><code><a 514href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code> 515</dt> 516<dd>這項屬性與 <a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a> 相似,但它在單一 Activity 上作業,而不是在整個工作。 517 518它也會導致任何 Activity 離開,包含根 Activity。 519如果設成 {@code "true"},Activity 只會在目前的工作階段留在此工作中。 520如果使用者離開後再回到工作,該工作將不再存在。 521</dd> 522</dl> 523 524 525 526 527<h3 id="Starting">開始工作</h3> 528 529<p>您可以給予 Activity 一個意圖篩選器,將 530{@code "android.intent.action.MAIN"} 設定為指定的動作, 531{@code "android.intent.category.LAUNCHER"} 設定為指定的類別,以便將該 Activity 設定為工作的進入點。 532例如:</p> 533 534<pre> 535<activity ... > 536 <intent-filter ... > 537 <action android:name="android.intent.action.MAIN" /> 538 <category android:name="android.intent.category.LAUNCHER" /> 539 </intent-filter> 540 ... 541</activity> 542</pre> 543 544<p>這類意圖篩選器可在應用程式啟動組件顯示 Activity 的圖示和標籤,讓使用者啟動 Activity 並回到 Activity 啟動後任何時間建立的工作。 545 546 547</p> 548 549<p>第二項功能很重要:使用者必須能夠在離開工作後,使用此 Activity 啟動組件回到此工作。 550由於這個原因,兩個將 Activity 標示為一律啟動工作的<a href="#LaunchModes">啟動模式</a> {@code "singleTask"} 和 551{@code "singleInstance"},應只能在 Activity 有 {@link android.content.Intent#ACTION_MAIN} 和 {@link android.content.Intent#CATEGORY_LAUNCHER} 篩選器時才能使用。 552 553 554例如,試想如果缺少篩選器會發生什麼情況: 555意圖會啟動 {@code "singleTask"} Activity、起始新工作,然後使用者會花一些時間在該工作進行作業。 556之後,使用者按下 [首頁]<em></em> 按鈕。 557此工作現在會傳送到背景而且不會顯示。現在,使用者沒有辦法回到工作,這是因為應用程式啟動組件沒有代表此工作的項目。 558</p> 559 560<p>在您不希望使用者返回 Activity 的情況下,將 561<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 元素的 562<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code finishOnTaskLaunch}</a> 設定為 {@code "true"} (請參閱<a href="#Clearing">清除堆疊</a>)。 563 564</p> 565 566<p>如要進一步瞭解工作和 Activity 在總覽畫面中的顯示及管理方式,請參閱<a href="{@docRoot}guide/components/recents.html">總覽畫面</a>。 567 568</p> 569 570<!-- 571<h2>Beginner's Path</h2> 572 573<p>For more information about how to use intents to 574activate other application components and publish the intents to which your components 575respond, continue with the <b><a 576href="{@docRoot}guide/components/intents-filters.html">Intents and Intent 577Filters</a></b> document.</p> 578--> 579