| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 1 | page.title=Tasks and Back Stack |
| 2 | parent.title=Activities |
| 3 | parent.link=activities.html |
| 4 | @jd:body |
| 5 | |
| 6 | <div id="qv-wrapper"> |
| 7 | <div id="qv"> |
| 8 | <h2>Quickview</h2> |
| 9 | <ul> |
| 10 | <li>All activities belong to a task</li> |
| 11 | <li>A task contains a collection of activities in the order in which the user interacts with |
| 12 | them</li> |
| 13 | <li>Tasks can move to the background and retain the state of each activity in order for users |
| 14 | to perform other tasks without losing their work</li> |
| 15 | </ul> |
| 16 | |
| 17 | <h2>In this document</h2> |
| 18 | <ol> |
| 19 | <li><a href="#ActivityState">Saving Activity State</a></li></li> |
| 20 | <li><a href="#ManagingTasks">Managing Tasks</a> |
| 21 | <ol> |
| 22 | <li><a href="#TaskLaunchModes">Defining launch modes</a></li> |
| 23 | <li><a href="#Affinities">Handling affinities</a></li> |
| 24 | <li><a href="#Clearing">Clearing the back stack</a></li> |
| 25 | <li><a href="#Starting">Starting a task</a></li> |
| 26 | </ol> |
| 27 | </li> |
| 28 | </ol> |
| 29 | |
| 30 | <h2>Articles</h2> |
| 31 | <ol> |
| 32 | <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html">Multitasking the Android Way</a></li> |
| 33 | </ol> |
| 34 | |
| 35 | <h2>See also</h2> |
| 36 | <ol> |
| 37 | <li><a href="{@docRoot}design/patterns/navigation.html">Android Design: |
| 38 | Navigation</a></li> |
| 39 | <li><a |
| 40 | href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>} manifest |
| 41 | element</a></li> |
| 42 | </ol> |
| 43 | </div> |
| 44 | </div> |
| 45 | |
| 46 | |
| 47 | <p>An application usually contains multiple <a |
| 48 | href="{@docRoot}guide/components/activities.html">activities</a>. Each activity |
| 49 | should be designed around a specific kind of action the user can perform and can start other |
| 50 | activities. For example, an email application might have one activity to show a list of new email. |
| 51 | When the user selects an email, a new activity opens to view that email.</p> |
| 52 | |
| 53 | <p>An activity can even start activities that exist in other applications on the device. For |
| 54 | example, if your application wants to send an email, you can define an intent to perform a "send" |
| 55 | action and include some data, such as an email address and a message. An activity from another |
| 56 | application that declares itself to handle this kind of intent then opens. In this case, the intent |
| 57 | is to send an email, so an email application's "compose" activity starts (if multiple activities |
| 58 | support the same intent, then the system lets the user select which one to use). When the email is |
| 59 | sent, your activity resumes and it seems as if the email activity was part of your application. Even |
| 60 | though the activities may be from different applications, Android maintains this seamless user |
| 61 | experience by keeping both activities in the same <em>task</em>.</p> |
| 62 | |
| 63 | <p>A task is a collection of activities that users interact with |
| 64 | when performing a certain job. The activities are arranged in a stack (the "back stack"), in the |
| 65 | order in which each activity is opened.</p> |
| 66 | |
| 67 | <!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED |
| 68 | <div class="sidebox-wrapper"> |
| 69 | <div class="sidebox"> |
| 70 | <h3>Adding fragments to a task's back stack</h3> |
| 71 | |
| 72 | <p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example, |
| 73 | suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the |
| 74 | other being a layout to display an item from the list (fragment B). When the user selects an item |
| 75 | from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be |
| 76 | desireable for the user to navigate back to reveal fragment B, using the <em>Back</em> button.</p> |
| 77 | <p>In order to add fragment B to the back stack so that this is possible, you must call {@link |
| 78 | android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link |
| 79 | android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment |
| 80 | C.</p> |
| 81 | <p>For more information about using fragments and adding them to the back stack, see the {@link |
| 82 | android.app.Fragment} class documentation.</p> |
| 83 | |
| 84 | </div> |
| 85 | </div> |
| 86 | --> |
| 87 | |
| 88 | <p>The device Home screen is the starting place for most tasks. When the user touches an icon in the |
| 89 | application |
| 90 | launcher (or a shortcut on the Home screen), that application's task comes to the foreground. If no |
| 91 | task exists for the application (the application has not been used recently), then a new task |
| 92 | is created and the "main" activity for that application opens as the root activity in the stack.</p> |
| 93 | |
| 94 | <p>When the current activity starts another, the new activity is pushed on the top of the stack and |
| 95 | takes focus. The previous activity remains in the stack, but is stopped. When an activity |
| 96 | stops, the system retains the current state of its user interface. When the user presses the |
| 97 | <em>Back</em> |
| 98 | button, the current activity is popped from the top of the stack (the activity is destroyed) and the |
| 99 | previous activity resumes (the previous state of its UI is restored). Activities in the stack are |
| 100 | never rearranged, only pushed and popped from the stack—pushed onto the stack when started by |
| 101 | the current activity and popped off when the user leaves it using the <em>Back</em> button. As such, |
| 102 | the back |
| 103 | stack operates as a "last in, first out" object structure. Figure 1 visualizes |
| 104 | this behavior with a timeline showing the progress between activities along with the current back |
| 105 | stack at each point in time.</p> |
| 106 | |
| 107 | <img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" /> |
| 108 | <p class="img-caption"><strong>Figure 1.</strong> A representation of how each new activity in a |
| 109 | task adds an item to the back stack. When the user presses the <em>Back</em> button, the current |
| 110 | activity is |
| 111 | destroyed and the previous activity resumes.</p> |
| 112 | |
| 113 | |
| 114 | <p>If the user continues to press <em>Back</em>, then each activity in the stack is popped off to |
| 115 | reveal the |
| 116 | previous one, until the user returns to the Home screen (or to whichever activity was running when |
| 117 | the task began). When all activities are removed from the stack, the task no longer exists.</p> |
| 118 | |
| 119 | <div class="figure" style="width:287px"> |
| 120 | <img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p |
| 121 | class="img-caption"><strong>Figure 2.</strong> Two tasks: Task B receives user interaction |
| 122 | in the foreground, while Task A is in the background, waiting to be resumed.</p> |
| 123 | </div> |
| 124 | <div class="figure" style="width:215px"> |
| 125 | <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p |
| 126 | class="img-caption"><strong>Figure 3.</strong> A single activity is instantiated multiple times.</p> |
| 127 | </div> |
| 128 | |
| 129 | <p>A task is a cohesive unit that can move to the "background" when users begin a new task or go |
| 130 | to the Home screen, via the <em>Home</em> button. While in the background, all the activities in the |
| 131 | task are |
| 132 | stopped, but the back stack for the task remains intact—the task has simply lost focus while |
| 133 | another task takes place, as shown in figure 2. A task can then return to the "foreground" so users |
| 134 | can pick up where they left off. Suppose, for example, that the current task (Task A) has three |
| 135 | activities in its stack—two under the current activity. The user presses the <em>Home</em> |
| 136 | button, then |
| 137 | starts a new application from the application launcher. When the Home screen appears, Task A goes |
| 138 | into the background. When the new application starts, the system starts a task for that application |
| 139 | (Task B) with its own stack of activities. After interacting with |
| 140 | that application, the user returns Home again and selects the application that originally |
| 141 | started Task A. Now, Task A comes to the |
| 142 | foreground—all three activities in its stack are intact and the activity at the top of the |
| 143 | stack resumes. At |
| 144 | this point, the user can also switch back to Task B by going Home and selecting the application icon |
| Scott Main | bde8ee8 | 2013-07-24 14:27:49 -0700 | [diff] [blame] | 145 | that started that task (or by selecting the app's task from the <em>recent apps</em> screen). |
| 146 | This is an example of multitasking on Android.</p> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 147 | |
| 148 | <p class="note"><strong>Note:</strong> Multiple tasks can be held in the background at once. |
| 149 | However, if the user is running many background tasks at the same time, the system might begin |
| 150 | destroying background activities in order to recover memory, causing the activity states to be lost. |
| 151 | See the following section about <a href="#ActivityState">Activity state</a>.</p> |
| 152 | |
| 153 | <p>Because the activities in the back stack are never rearranged, if your application allows |
| 154 | users to start a particular activity from more than one activity, a new instance of |
| 155 | that activity is created and pushed onto the stack (rather than bringing any previous instance of |
| 156 | the activity to the top). As such, one activity in your application might be instantiated multiple |
| 157 | times (even from different tasks), as shown in figure 3. As such, if the user navigates backward |
| 158 | using the <em>Back</em> button, each instance of the activity is revealed in the order they were |
| 159 | opened (each |
| 160 | with their own UI state). However, you can modify this behavior if you do not want an activity to be |
| 161 | instantiated more than once. How to do so is discussed in the later section about <a |
| 162 | href="#ManagingTasks">Managing Tasks</a>.</p> |
| 163 | |
| 164 | |
| 165 | <p>To summarize the default behavior for activities and tasks:</p> |
| 166 | |
| 167 | <ul> |
| 168 | <li>When Activity A starts Activity B, Activity A is stopped, but the system retains its state |
| 169 | (such as scroll position and text entered into forms). |
| 170 | If the user presses the <em>Back</em> button while in Activity B, Activity A resumes with its state |
| 171 | restored.</li> |
| 172 | <li>When the user leaves a task by pressing the <em>Home</em> button, the current activity is |
| 173 | stopped and |
| 174 | its task goes into the background. The system retains the state of every activity in the task. If |
| 175 | the user later resumes the task by selecting the launcher icon that began the task, the task comes |
| 176 | to the foreground and resumes the activity at the top of the stack.</li> |
| 177 | <li>If the user presses the <em>Back</em> button, the current activity is popped from the stack |
| 178 | and |
| 179 | destroyed. The previous activity in the stack is resumed. When an activity is destroyed, the system |
| 180 | <em>does not</em> retain the activity's state.</li> |
| 181 | <li>Activities can be instantiated multiple times, even from other tasks.</li> |
| 182 | </ul> |
| 183 | |
| 184 | |
| Scott Main | 91b5ecc | 2012-06-22 13:26:08 -0700 | [diff] [blame] | 185 | <div class="note design"> |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 186 | <p><strong>Navigation Design</strong></p> |
| 187 | <p>For more about how app navigation works on Android, read Android Design's <a |
| 188 | href="{@docRoot}design/patterns/navigation.html">Navigation</a> guide.</p> |
| 189 | </div> |
| 190 | |
| 191 | |
| 192 | <h2 id="ActivityState">Saving Activity State</h2> |
| 193 | |
| 194 | <p>As discussed above, the system's default behavior preserves the state of an activity when it is |
| 195 | stopped. This way, when users navigate back to a previous activity, its user interface appears |
| 196 | the way they left it. However, you can—and <strong>should</strong>—proactively retain |
| 197 | the state of your activities using callback methods, in case the activity is destroyed and must |
| 198 | be recreated.</p> |
| 199 | |
| 200 | <p>When the system stops one of your activities (such as when a new activity starts or the task |
| 201 | moves to the background), the system might destroy that activity completely if it needs to recover |
| 202 | system memory. When this happens, information about the activity state is lost. If this happens, the |
| 203 | system still |
| 204 | knows that the activity has a place in the back stack, but when the activity is brought to the |
| 205 | top of the stack the system must recreate it (rather than resume it). In order to |
| 206 | avoid losing the user's work, you should proactively retain it by implementing the {@link |
| 207 | android.app.Activity#onSaveInstanceState onSaveInstanceState()} callback |
| 208 | methods in your activity.</p> |
| 209 | |
| 210 | <p>For more information about how to save your activity state, see the <a |
| 211 | href="{@docRoot}guide/components/activities.html#SavingActivityState">Activities</a> |
| 212 | document.</p> |
| 213 | |
| 214 | |
| 215 | |
| 216 | <h2 id="ManagingTasks">Managing Tasks</h2> |
| 217 | |
| 218 | <p>The way Android manages tasks and the back stack, as described above—by placing all |
| 219 | activities started in succession in the same task and in a "last in, first out" stack—works |
| 220 | great for most applications and you shouldn't have to worry about how your activities are associated |
| 221 | with tasks or how they exist in the back stack. However, you might decide that you want to interrupt |
| 222 | the normal behavior. Perhaps you want an activity in your application to begin a new task when it is |
| 223 | started (instead of being placed within the current task); or, when you start an activity, you want |
| 224 | to bring forward an existing instance of it (instead of creating a new |
| 225 | instance on top of the back stack); or, you want your back stack to be cleared of all |
| 226 | activities except for the root activity when the user leaves the task.</p> |
| 227 | |
| 228 | <p>You can do these things and more, with attributes in the |
| 229 | <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code |
| 230 | <activity>}</a> manifest element and with flags in the intent that you pass to {@link |
| 231 | android.app.Activity#startActivity startActivity()}.</p> |
| 232 | |
| kmccormick | 76dfc02 | 2013-04-03 12:41:12 -0700 | [diff] [blame] | 233 | <p>In this regard, the principal <a |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 234 | href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> |
| 235 | attributes you can use are:</p> |
| 236 | |
| 237 | <ul class="nolist"> |
| 238 | <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code |
| 239 | taskAffinity}</a></li> |
| 240 | <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code |
| 241 | launchMode}</a></li> |
| 242 | <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code |
| 243 | allowTaskReparenting}</a></li> |
| 244 | <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code |
| 245 | clearTaskOnLaunch}</a></li> |
| 246 | <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code |
| 247 | alwaysRetainTaskState}</a></li> |
| 248 | <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code |
| 249 | finishOnTaskLaunch}</a></li> |
| 250 | </ul> |
| 251 | |
| 252 | <p>And the principal intent flags you can use are:</p> |
| 253 | |
| 254 | <ul class="nolist"> |
| 255 | <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li> |
| 256 | <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li> |
| 257 | <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li> |
| 258 | </ul> |
| 259 | |
| 260 | <p>In the following sections, you'll see how you can use these manifest attributes and intent |
| 261 | flags to define how activities are associated with tasks and how the behave in the back stack.</p> |
| 262 | |
| 263 | |
| 264 | <p class="caution"><strong>Caution:</strong> Most applications should not interrupt the default |
| 265 | behavior for activities and tasks. If you determine that it's necessary for your activity to modify |
| 266 | the default behaviors, use caution and be sure to test the usability of the activity during |
| 267 | launch and when navigating back to it from other activities and tasks with the <em>Back</em> button. |
| 268 | Be sure |
| 269 | to test for navigation behaviors that might conflict with the user's expected behavior.</p> |
| 270 | |
| 271 | |
| 272 | <h3 id="TaskLaunchModes">Defining launch modes</h3> |
| 273 | |
| 274 | <p>Launch modes allow you to define how a new instance of an activity is associated with the |
| 275 | current task. You can define different launch modes in two ways:</p> |
| 276 | <ul class="nolist"> |
| 277 | <li><a href="#ManifestForTasks">Using the manifest file</a> |
| 278 | <p>When you declare an activity in your manifest file, you can specify how the activity |
| 279 | should associate with tasks when it starts.</li> |
| 280 | <li><a href="#IntentFlagsForTasks">Using Intent flags</a> |
| 281 | <p>When you call {@link android.app.Activity#startActivity startActivity()}, |
| 282 | you can include a flag in the {@link android.content.Intent} that declares how (or |
| 283 | whether) the new activity should associate with the current task.</p></li> |
| 284 | </ul> |
| 285 | |
| 286 | <p>As such, if Activity A starts Activity B, Activity B can define in its manifest how it |
| 287 | should associate with the current task (if at all) and Activity A can also request how Activity |
| 288 | B should associate with current task. If both activities define how Activity B |
| 289 | should associate with a task, then Activity A's request (as defined in the intent) is honored |
| 290 | over Activity B's request (as defined in its manifest).</p> |
| 291 | |
| 292 | <p class="note"><strong>Note:</strong> Some launch modes available for the manifest file |
| 293 | are not available as flags for an intent and, likewise, some launch modes available as flags |
| 294 | for an intent cannot be defined in the manifest.</p> |
| 295 | |
| 296 | |
| 297 | <h4 id="ManifestForTasks">Using the manifest file</h4> |
| 298 | |
| 299 | <p>When declaring an activity in your manifest file, you can specify how the activity should |
| 300 | associate with a task using the <a |
| 301 | href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> |
| 302 | element's <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code |
| 303 | launchMode}</a> attribute.</p> |
| 304 | |
| 305 | <p>The <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code |
| 306 | launchMode}</a> attribute specifies an instruction on how the activity should be launched into a |
| 307 | task. There are four different launch modes you can assign to the |
| 308 | <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code> |
| 309 | attribute:</p> |
| 310 | |
| 311 | <dl> |
| 312 | <dt>{@code "standard"} (the default mode)</dt> |
| 313 | <dd>Default. The system creates a new instance of the activity in the task from |
| 314 | which it was started and routes the intent to it. The activity can be instantiated multiple times, |
| 315 | each instance can belong to different tasks, and one task can have multiple instances.</dd> |
| 316 | <dt>{@code "singleTop"}</dt> |
| 317 | <dd>If an instance of the activity already exists at the top of the current task, the system |
| 318 | routes the intent to that instance through a call to its {@link |
| 319 | android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a new instance of the |
| 320 | activity. The activity can be instantiated multiple times, each instance can |
| kmccormick | 76dfc02 | 2013-04-03 12:41:12 -0700 | [diff] [blame] | 321 | belong to different tasks, and one task can have multiple instances (but only if the |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 322 | activity at the top of the back stack is <em>not</em> an existing instance of the activity). |
| 323 | <p>For example, suppose a task's back stack consists of root activity A with activities B, C, |
| 324 | and D on top (the stack is A-B-C-D; D is on top). An intent arrives for an activity of type D. |
| 325 | If D has the default {@code "standard"} launch mode, a new instance of the class is launched and the |
| 326 | stack becomes A-B-C-D-D. However, if D's launch mode is {@code "singleTop"}, the existing instance |
| 327 | of D receives the intent through {@link |
| 328 | android.app.Activity#onNewIntent onNewIntent()}, because it's at the top of the stack—the |
| 329 | stack remains A-B-C-D. However, if an intent arrives for an activity of type B, then a new |
| 330 | instance of B is added to the stack, even if its launch mode is {@code "singleTop"}.</p> |
| 331 | <p class="note"><strong>Note:</strong> When a new instance of an activity is created, |
| 332 | the user can press the <em>Back</em> button to return to the previous activity. But when an existing |
| 333 | instance of |
| 334 | an activity handles a new intent, the user cannot press the <em>Back</em> button to return to the |
| 335 | state of |
| 336 | the activity before the new intent arrived in {@link android.app.Activity#onNewIntent |
| 337 | onNewIntent()}.</p> |
| 338 | </dd> |
| 339 | |
| 340 | <dt>{@code "singleTask"}</dt> |
| 341 | <dd>The system creates a new task and instantiates the activity at the root of the new task. |
| 342 | However, if an instance of the activity already exists in a separate task, the system routes the |
| 343 | intent to the existing instance through a call to its {@link |
| 344 | android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a new instance. Only |
| 345 | one instance of the activity can exist at a time. |
| 346 | <p class="note"><strong>Note:</strong> Although the activity starts in a new task, the |
| 347 | <em>Back</em> button still returns the user to the previous activity.</p></dd> |
| 348 | <dt>{@code "singleInstance"}.</dt> |
| 349 | <dd>Same as {@code "singleTask"}, except that the system doesn't launch any other activities into |
| 350 | the task holding the instance. The activity is always the single and only member of its task; |
| 351 | any activities started by this one open in a separate task.</dd> |
| 352 | </dl> |
| 353 | |
| 354 | |
| 355 | <p>As another example, the Android Browser application declares that the web browser activity should |
| 356 | always open in its own task—by specifying the {@code singleTask} launch mode in the <a |
| 357 | href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element. |
| 358 | This means that if your application issues an |
| 359 | intent to open the Android Browser, its activity is <em>not</em> placed in the same |
| 360 | task as your application. Instead, either a new task starts for the Browser or, if the Browser |
| 361 | already has a task running in the background, that task is brought forward to handle the new |
| 362 | intent.</p> |
| 363 | |
| 364 | <p>Regardless of whether an activity starts in a new task or in the same task as the activity that |
| 365 | started it, the <em>Back</em> button always takes the user to the previous activity. However, if you |
| 366 | start an activity that specifies the {@code singleTask} launch mode, then if an instance of |
| 367 | that activity exists in a background task, that whole task is brought to the foreground. At this |
| 368 | point, the back stack now includes all activities from the task brought forward, at the top of the |
| 369 | stack. Figure 4 illustrates this type of scenario.</p> |
| 370 | |
| 371 | <img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" /> |
| 372 | <p class="img-caption"><strong>Figure 4.</strong> A representation of how an activity with |
| 373 | launch mode "singleTask" is added to the back stack. If the activity is already a part of a |
| 374 | background task with its own back stack, then the entire back stack also comes |
| 375 | forward, on top of the current task.</p> |
| 376 | |
| 377 | <p>For more information about using launch modes in the manifest file, see the |
| 378 | <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> |
| 379 | element documentation, where the {@code launchMode} attribute and the accepted values are |
| 380 | discussed more.</p> |
| 381 | |
| 382 | <p class="note"><strong>Note:</strong> The behaviors that you specify for your activity with the <a |
| 383 | href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> attribute |
| 384 | can be overridden by flags included with the intent that start your activity, as discussed in the |
| 385 | next section.</p> |
| 386 | |
| 387 | |
| 388 | |
| 389 | <h4 id="#IntentFlagsForTasks">Using Intent flags</h4> |
| 390 | |
| 391 | <p>When starting an activity, you can modify the default association of an activity to its task |
| 392 | by including flags in the intent that you deliver to {@link |
| 393 | android.app.Activity#startActivity startActivity()}. The flags you can use to modify the |
| 394 | default behavior are:</p> |
| 395 | |
| 396 | <p> |
| 397 | <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt> |
| 398 | <dd>Start the activity in a new task. If a task is already running for the activity you are now |
| 399 | starting, that task is brought to the foreground with its last state restored and the activity |
| 400 | receives the new intent in {@link android.app.Activity#onNewIntent onNewIntent()}. |
| 401 | <p>This produces the same behavior as the {@code "singleTask"} <a |
| 402 | href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> value, |
| 403 | discussed in the previous section.</p></dd> |
| 404 | <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt> |
| 405 | <dd>If the activity being started is the current activity (at the top of the back stack), then |
| 406 | the existing instance receives a call to {@link android.app.Activity#onNewIntent onNewIntent()}, |
| 407 | instead of creating a new instance of the activity. |
| 408 | <p>This produces the same behavior as the {@code "singleTop"} <a |
| 409 | href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> value, |
| 410 | discussed in the previous section.</p></dd> |
| 411 | <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt> |
| 412 | <dd>If the activity being started is already running in the current task, then instead |
| 413 | of launching a new instance of that activity, all of the other activities on top of it are |
| 414 | destroyed and this intent is delivered to the resumed instance of the activity (now on top), |
| 415 | through {@link android.app.Activity#onNewIntent onNewIntent()}). |
| 416 | <p>There is no value for the <a |
| 417 | href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> |
| 418 | attribute that produces this behavior.</p> |
| 419 | <p>{@code FLAG_ACTIVITY_CLEAR_TOP} is most often used in conjunction with {@code |
| 420 | FLAG_ACTIVITY_NEW_TASK}. When used together, these flags are a way of locating an existing activity |
| 421 | in another task and putting it in a position where it can respond to the intent. </p> |
| 422 | <p class="note"><strong>Note:</strong> If the launch mode of the designated activity is {@code |
| 423 | "standard"}, it too is removed from the stack and a new instance is launched in its place to handle |
| 424 | the incoming intent. That's because a new instance is always created for a new intent when the |
| 425 | launch mode is {@code "standard"}. </p> |
| 426 | </dd> |
| 427 | </dl> |
| 428 | |
| 429 | |
| 430 | |
| 431 | |
| 432 | |
| 433 | <h3 id="Affinities">Handling affinities</h3> |
| 434 | |
| 435 | <p>The <em>affinity</em> indicates which task an activity prefers to belong to. By default, all the |
| 436 | activities from the same application have an affinity for each other. So, by default, all |
| 437 | activities in the same application prefer to be in the same task. However, you can modify |
| 438 | the default affinity for an activity. Activities defined in |
| 439 | different applications can share an affinity, or activities defined in the same application can be |
| 440 | assigned different task affinities.</p> |
| 441 | |
| 442 | <p>You can modify the affinity for any given activity with the <a |
| 443 | href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> attribute |
| 444 | of the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> |
| 445 | element.</p> |
| 446 | |
| 447 | <p>The <a |
| 448 | href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> |
| 449 | attribute takes a string value, which must be unique from the default package name |
| 450 | declared in the <a href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code |
| 451 | <manifest>}</a> element, because the system uses that name to identify the default task |
| 452 | affinity for the application.</p> |
| 453 | |
| 454 | <p>The affinity comes into play in two circumstances:</p> |
| 455 | <ul> |
| 456 | <li>When the intent that launches an activity contains the {@link |
| 457 | android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag. |
| 458 | |
| 459 | <p>A new activity is, by default, launched into the task of the activity |
| 460 | that called {@link android.app.Activity#startActivity startActivity()}. It's pushed onto the same |
| 461 | back stack as the caller. However, if the intent passed to {@link |
| 462 | android.app.Activity#startActivity startActivity()} contains the {@link |
| 463 | android.content.Intent#FLAG_ACTIVITY_NEW_TASK} |
| 464 | flag, the system looks for a different task to house the new activity. Often, it's a new task. |
| 465 | However, it doesn't have to be. If there's already an existing task with the same affinity as the |
| 466 | new activity, the activity is launched into that task. If not, it begins a new task.</p> |
| 467 | |
| 468 | <p>If this flag causes an activity to begin a new task and the user presses the <em>Home</em> button |
| 469 | to leave |
| 470 | it, there must be some way for the user to navigate back to the task. Some entities (such as the |
| 471 | notification manager) always start activities in an external task, never as part of their own, so |
| 472 | they always put {@code FLAG_ACTIVITY_NEW_TASK} in the intents they pass to {@link |
| 473 | android.app.Activity#startActivity startActivity()}. If you have an activity that can be invoked by |
| 474 | an external entity that might use this flag, take care that the user has a independent way to get |
| 475 | back to the task that's started, such as with a launcher icon (the root activity of the task |
| 476 | has a {@link android.content.Intent#CATEGORY_LAUNCHER} intent filter; see the <a |
| 477 | href="#Starting">Starting a task</a> section below).</p> |
| 478 | </li> |
| 479 | |
| 480 | <li>When an activity has its <a |
| 481 | href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code |
| 482 | allowTaskReparenting}</a> attribute set to {@code "true"}. |
| 483 | <p>In this case, the activity can move from the task it starts to the task it has an affinity |
| 484 | for, when that task comes to the foreground.</p> |
| 485 | <p>For example, suppose that an activity that reports weather conditions in selected cities is |
| 486 | defined as part of a travel application. It has the same affinity as other activities in the same |
| 487 | application (the default application affinity) and it allows re-parenting with this attribute. |
| 488 | When one of your activities starts the weather reporter activity, it initially belongs to the same |
| 489 | task as your activity. However, when the travel application's task comes to the foreground, the |
| 490 | weather reporter activity is reassigned to that task and displayed within it.</p> |
| 491 | </li> |
| 492 | </ul> |
| 493 | |
| 494 | <p class="note"><strong>Tip:</strong> If an {@code .apk} file contains more than one "application" |
| 495 | from the user's point of view, you probably want to use the <a |
| 496 | href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> |
| 497 | attribute to assign different affinities to the activities associated with each "application".</p> |
| 498 | |
| 499 | |
| 500 | |
| 501 | <h3 id="Clearing">Clearing the back stack</h3> |
| 502 | |
| 503 | <p>If the user leaves a task for a long time, the system clears the task of all activities except |
| 504 | the root activity. When the user returns to the task again, only the root activity is restored. |
| 505 | The system behaves this way, because, after an extended amount of time, users likely have abandoned |
| 506 | what they were doing before and are returning to the task to begin something new. </p> |
| 507 | |
| 508 | <p>There are some activity attributes that you can use to modify this behavior: </p> |
| 509 | |
| 510 | <dl> |
| 511 | <dt><code><a |
| 512 | href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code> |
| 513 | </dt> |
| 514 | <dd>If this attribute is set to {@code "true"} in the root activity of a task, |
| 515 | the default behavior just described does not happen. |
| 516 | The task retains all activities in its stack even after a long period.</dd> |
| 517 | |
| 518 | <dt><code><a |
| 519 | href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt> |
| 520 | <dd>If this attribute is set to {@code "true"} in the root activity of a task, |
| 521 | the stack is cleared down to the root activity whenever the user leaves the task |
| 522 | and returns to it. In other words, it's the opposite of <a |
| 523 | href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code |
| 524 | alwaysRetainTaskState}</a>. The user always returns to the task in its |
| 525 | initial state, even after a leaving the task for only a moment.</dd> |
| 526 | |
| 527 | <dt><code><a |
| 528 | href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code> |
| 529 | </dt> |
| 530 | <dd>This attribute is like <a |
| 531 | href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a>, |
| 532 | but it operates on a |
| 533 | single activity, not an entire task. It can also cause any activity to go |
| 534 | away, including the root activity. When it's set to {@code "true"}, the |
| 535 | activity remains part of the task only for the current session. If the user |
| 536 | leaves and then returns to the task, it is no longer present.</dd> |
| 537 | </dl> |
| 538 | |
| 539 | |
| 540 | |
| 541 | |
| 542 | <h3 id="Starting">Starting a task</h3> |
| 543 | |
| 544 | <p>You can set up an activity as the entry point for a task by giving it an intent filter with |
| 545 | {@code "android.intent.action.MAIN"} as the specified action and {@code |
| 546 | "android.intent.category.LAUNCHER"} as the specified category. For example:</p> |
| 547 | |
| 548 | <pre> |
| 549 | <activity ... > |
| 550 | <intent-filter ... > |
| 551 | <action android:name="android.intent.action.MAIN" /> |
| 552 | <category android:name="android.intent.category.LAUNCHER" /> |
| 553 | </intent-filter> |
| 554 | ... |
| 555 | </activity> |
| 556 | </pre> |
| 557 | |
| 558 | <p>An intent filter of this kind causes an icon and label for the |
| 559 | activity to be displayed in the application launcher, giving users a way to launch the activity and |
| 560 | to return to the task that it creates any time after it has been launched. |
| 561 | </p> |
| 562 | |
| 563 | <p>This second ability is important: Users must be able to leave a task and then come back to it |
| 564 | later using this activity launcher. For this reason, the two <a href="#LaunchModes">launch |
| 565 | modes</a> that mark activities as always initiating a task, {@code "singleTask"} and "{@code |
| 566 | "singleInstance"}, should be used only when the activity has an {@link |
| 567 | android.content.Intent#ACTION_MAIN} |
| 568 | and a {@link android.content.Intent#CATEGORY_LAUNCHER} |
| 569 | filter. Imagine, for example, what could happen if the filter is missing: An intent launches a |
| 570 | {@code "singleTask"} activity, initiating a new task, and the user spends some time working in |
| 571 | that task. The user then presses the <em>Home</em> button. The task is now sent to the background |
| 572 | and is |
| 573 | not visible. Now the user has no way to return to the task, because it is not represented in the |
| 574 | application launcher. |
| 575 | </p> |
| 576 | |
| 577 | <p>For those cases where you don't want the user to be able to return to an activity, set the |
| 578 | <code><a |
| 579 | href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> element's |
| 580 | <a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code |
| 581 | finishOnTaskLaunch}</a> to {@code "true"} (see <a |
| 582 | href="#Clearing">Clearing the stack</a>).</p> |
| 583 | |
| 584 | |
| 585 | |
| 586 | <!-- |
| 587 | <h2>Beginner's Path</h2> |
| 588 | |
| 589 | <p>For more information about how to use intents to |
| 590 | activate other application components and publish the intents to which your components |
| 591 | respond, continue with the <b><a |
| 592 | href="{@docRoot}guide/components/intents-filters.html">Intents and Intent |
| 593 | Filters</a></b> document.</p> |
| 594 | --> |