bde8ee81ba
bug: 10004058 Change-Id: I21ee82fca2f07b00a47fb80e9ebd50e5c944e3fc
595 lines
32 KiB
Plaintext
595 lines
32 KiB
Plaintext
page.title=Tasks and Back Stack
|
|
parent.title=Activities
|
|
parent.link=activities.html
|
|
@jd:body
|
|
|
|
<div id="qv-wrapper">
|
|
<div id="qv">
|
|
<h2>Quickview</h2>
|
|
<ul>
|
|
<li>All activities belong to a task</li>
|
|
<li>A task contains a collection of activities in the order in which the user interacts with
|
|
them</li>
|
|
<li>Tasks can move to the background and retain the state of each activity in order for users
|
|
to perform other tasks without losing their work</li>
|
|
</ul>
|
|
|
|
<h2>In this document</h2>
|
|
<ol>
|
|
<li><a href="#ActivityState">Saving Activity State</a></li></li>
|
|
<li><a href="#ManagingTasks">Managing Tasks</a>
|
|
<ol>
|
|
<li><a href="#TaskLaunchModes">Defining launch modes</a></li>
|
|
<li><a href="#Affinities">Handling affinities</a></li>
|
|
<li><a href="#Clearing">Clearing the back stack</a></li>
|
|
<li><a href="#Starting">Starting a task</a></li>
|
|
</ol>
|
|
</li>
|
|
</ol>
|
|
|
|
<h2>Articles</h2>
|
|
<ol>
|
|
<li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html">Multitasking the Android Way</a></li>
|
|
</ol>
|
|
|
|
<h2>See also</h2>
|
|
<ol>
|
|
<li><a href="{@docRoot}design/patterns/navigation.html">Android Design:
|
|
Navigation</a></li>
|
|
<li><a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>} manifest
|
|
element</a></li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<p>An application usually contains multiple <a
|
|
href="{@docRoot}guide/components/activities.html">activities</a>. Each activity
|
|
should be designed around a specific kind of action the user can perform and can start other
|
|
activities. For example, an email application might have one activity to show a list of new email.
|
|
When the user selects an email, a new activity opens to view that email.</p>
|
|
|
|
<p>An activity can even start activities that exist in other applications on the device. For
|
|
example, if your application wants to send an email, you can define an intent to perform a "send"
|
|
action and include some data, such as an email address and a message. An activity from another
|
|
application that declares itself to handle this kind of intent then opens. In this case, the intent
|
|
is to send an email, so an email application's "compose" activity starts (if multiple activities
|
|
support the same intent, then the system lets the user select which one to use). When the email is
|
|
sent, your activity resumes and it seems as if the email activity was part of your application. Even
|
|
though the activities may be from different applications, Android maintains this seamless user
|
|
experience by keeping both activities in the same <em>task</em>.</p>
|
|
|
|
<p>A task is a collection of activities that users interact with
|
|
when performing a certain job. The activities are arranged in a stack (the "back stack"), in the
|
|
order in which each activity is opened.</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>The device Home screen is the starting place for most tasks. When the user touches an icon in the
|
|
application
|
|
launcher (or a shortcut on the Home screen), that application's task comes to the foreground. If no
|
|
task exists for the application (the application has not been used recently), then a new task
|
|
is created and the "main" activity for that application opens as the root activity in the stack.</p>
|
|
|
|
<p>When the current activity starts another, the new activity is pushed on the top of the stack and
|
|
takes focus. The previous activity remains in the stack, but is stopped. When an activity
|
|
stops, the system retains the current state of its user interface. When the user presses the
|
|
<em>Back</em>
|
|
button, the current activity is popped from the top of the stack (the activity is destroyed) and the
|
|
previous activity resumes (the previous state of its UI is restored). Activities in the stack are
|
|
never rearranged, only pushed and popped from the stack—pushed onto the stack when started by
|
|
the current activity and popped off when the user leaves it using the <em>Back</em> button. As such,
|
|
the back
|
|
stack operates as a "last in, first out" object structure. Figure 1 visualizes
|
|
this behavior with a timeline showing the progress between activities along with the current back
|
|
stack at each point in time.</p>
|
|
|
|
<img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" />
|
|
<p class="img-caption"><strong>Figure 1.</strong> A representation of how each new activity in a
|
|
task adds an item to the back stack. When the user presses the <em>Back</em> button, the current
|
|
activity is
|
|
destroyed and the previous activity resumes.</p>
|
|
|
|
|
|
<p>If the user continues to press <em>Back</em>, then each activity in the stack is popped off to
|
|
reveal the
|
|
previous one, until the user returns to the Home screen (or to whichever activity was running when
|
|
the task began). When all activities are removed from the stack, the task no longer exists.</p>
|
|
|
|
<div class="figure" style="width:287px">
|
|
<img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p
|
|
class="img-caption"><strong>Figure 2.</strong> Two tasks: Task B receives user interaction
|
|
in the foreground, while Task A is in the background, waiting to be resumed.</p>
|
|
</div>
|
|
<div class="figure" style="width:215px">
|
|
<img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p
|
|
class="img-caption"><strong>Figure 3.</strong> A single activity is instantiated multiple times.</p>
|
|
</div>
|
|
|
|
<p>A task is a cohesive unit that can move to the "background" when users begin a new task or go
|
|
to the Home screen, via the <em>Home</em> button. While in the background, all the activities in the
|
|
task are
|
|
stopped, but the back stack for the task remains intact—the task has simply lost focus while
|
|
another task takes place, as shown in figure 2. A task can then return to the "foreground" so users
|
|
can pick up where they left off. Suppose, for example, that the current task (Task A) has three
|
|
activities in its stack—two under the current activity. The user presses the <em>Home</em>
|
|
button, then
|
|
starts a new application from the application launcher. When the Home screen appears, Task A goes
|
|
into the background. When the new application starts, the system starts a task for that application
|
|
(Task B) with its own stack of activities. After interacting with
|
|
that application, the user returns Home again and selects the application that originally
|
|
started Task A. Now, Task A comes to the
|
|
foreground—all three activities in its stack are intact and the activity at the top of the
|
|
stack resumes. At
|
|
this point, the user can also switch back to Task B by going Home and selecting the application icon
|
|
that started that task (or by selecting the app's task from the <em>recent apps</em> screen).
|
|
This is an example of multitasking on Android.</p>
|
|
|
|
<p class="note"><strong>Note:</strong> Multiple tasks can be held in the background at once.
|
|
However, if the user is running many background tasks at the same time, the system might begin
|
|
destroying background activities in order to recover memory, causing the activity states to be lost.
|
|
See the following section about <a href="#ActivityState">Activity state</a>.</p>
|
|
|
|
<p>Because the activities in the back stack are never rearranged, if your application allows
|
|
users to start a particular activity from more than one activity, a new instance of
|
|
that activity is created and pushed onto the stack (rather than bringing any previous instance of
|
|
the activity to the top). As such, one activity in your application might be instantiated multiple
|
|
times (even from different tasks), as shown in figure 3. As such, if the user navigates backward
|
|
using the <em>Back</em> button, each instance of the activity is revealed in the order they were
|
|
opened (each
|
|
with their own UI state). However, you can modify this behavior if you do not want an activity to be
|
|
instantiated more than once. How to do so is discussed in the later section about <a
|
|
href="#ManagingTasks">Managing Tasks</a>.</p>
|
|
|
|
|
|
<p>To summarize the default behavior for activities and tasks:</p>
|
|
|
|
<ul>
|
|
<li>When Activity A starts Activity B, Activity A is stopped, but the system retains its state
|
|
(such as scroll position and text entered into forms).
|
|
If the user presses the <em>Back</em> button while in Activity B, Activity A resumes with its state
|
|
restored.</li>
|
|
<li>When the user leaves a task by pressing the <em>Home</em> button, the current activity is
|
|
stopped and
|
|
its task goes into the background. The system retains the state of every activity in the task. If
|
|
the user later resumes the task by selecting the launcher icon that began the task, the task comes
|
|
to the foreground and resumes the activity at the top of the stack.</li>
|
|
<li>If the user presses the <em>Back</em> button, the current activity is popped from the stack
|
|
and
|
|
destroyed. The previous activity in the stack is resumed. When an activity is destroyed, the system
|
|
<em>does not</em> retain the activity's state.</li>
|
|
<li>Activities can be instantiated multiple times, even from other tasks.</li>
|
|
</ul>
|
|
|
|
|
|
<div class="note design">
|
|
<p><strong>Navigation Design</strong></p>
|
|
<p>For more about how app navigation works on Android, read Android Design's <a
|
|
href="{@docRoot}design/patterns/navigation.html">Navigation</a> guide.</p>
|
|
</div>
|
|
|
|
|
|
<h2 id="ActivityState">Saving Activity State</h2>
|
|
|
|
<p>As discussed above, the system's default behavior preserves the state of an activity when it is
|
|
stopped. This way, when users navigate back to a previous activity, its user interface appears
|
|
the way they left it. However, you can—and <strong>should</strong>—proactively retain
|
|
the state of your activities using callback methods, in case the activity is destroyed and must
|
|
be recreated.</p>
|
|
|
|
<p>When the system stops one of your activities (such as when a new activity starts or the task
|
|
moves to the background), the system might destroy that activity completely if it needs to recover
|
|
system memory. When this happens, information about the activity state is lost. If this happens, the
|
|
system still
|
|
knows that the activity has a place in the back stack, but when the activity is brought to the
|
|
top of the stack the system must recreate it (rather than resume it). In order to
|
|
avoid losing the user's work, you should proactively retain it by implementing the {@link
|
|
android.app.Activity#onSaveInstanceState onSaveInstanceState()} callback
|
|
methods in your activity.</p>
|
|
|
|
<p>For more information about how to save your activity state, see the <a
|
|
href="{@docRoot}guide/components/activities.html#SavingActivityState">Activities</a>
|
|
document.</p>
|
|
|
|
|
|
|
|
<h2 id="ManagingTasks">Managing Tasks</h2>
|
|
|
|
<p>The way Android manages tasks and the back stack, as described above—by placing all
|
|
activities started in succession in the same task and in a "last in, first out" stack—works
|
|
great for most applications and you shouldn't have to worry about how your activities are associated
|
|
with tasks or how they exist in the back stack. However, you might decide that you want to interrupt
|
|
the normal behavior. Perhaps you want an activity in your application to begin a new task when it is
|
|
started (instead of being placed within the current task); or, when you start an activity, you want
|
|
to bring forward an existing instance of it (instead of creating a new
|
|
instance on top of the back stack); or, you want your back stack to be cleared of all
|
|
activities except for the root activity when the user leaves the task.</p>
|
|
|
|
<p>You can do these things and more, with attributes in the
|
|
<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
|
|
<activity>}</a> manifest element and with flags in the intent that you pass to {@link
|
|
android.app.Activity#startActivity startActivity()}.</p>
|
|
|
|
<p>In this regard, the principal <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>
|
|
attributes you can use are:</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>And the principal intent flags you can use are:</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>In the following sections, you'll see how you can use these manifest attributes and intent
|
|
flags to define how activities are associated with tasks and how the behave in the back stack.</p>
|
|
|
|
|
|
<p class="caution"><strong>Caution:</strong> Most applications should not interrupt the default
|
|
behavior for activities and tasks. If you determine that it's necessary for your activity to modify
|
|
the default behaviors, use caution and be sure to test the usability of the activity during
|
|
launch and when navigating back to it from other activities and tasks with the <em>Back</em> button.
|
|
Be sure
|
|
to test for navigation behaviors that might conflict with the user's expected behavior.</p>
|
|
|
|
|
|
<h3 id="TaskLaunchModes">Defining launch modes</h3>
|
|
|
|
<p>Launch modes allow you to define how a new instance of an activity is associated with the
|
|
current task. You can define different launch modes in two ways:</p>
|
|
<ul class="nolist">
|
|
<li><a href="#ManifestForTasks">Using the manifest file</a>
|
|
<p>When you declare an activity in your manifest file, you can specify how the activity
|
|
should associate with tasks when it starts.</li>
|
|
<li><a href="#IntentFlagsForTasks">Using Intent flags</a>
|
|
<p>When you call {@link android.app.Activity#startActivity startActivity()},
|
|
you can include a flag in the {@link android.content.Intent} that declares how (or
|
|
whether) the new activity should associate with the current task.</p></li>
|
|
</ul>
|
|
|
|
<p>As such, if Activity A starts Activity B, Activity B can define in its manifest how it
|
|
should associate with the current task (if at all) and Activity A can also request how Activity
|
|
B should associate with current task. If both activities define how Activity B
|
|
should associate with a task, then Activity A's request (as defined in the intent) is honored
|
|
over Activity B's request (as defined in its manifest).</p>
|
|
|
|
<p class="note"><strong>Note:</strong> Some launch modes available for the manifest file
|
|
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.</p>
|
|
|
|
|
|
<h4 id="ManifestForTasks">Using the manifest file</h4>
|
|
|
|
<p>When declaring an activity in your manifest file, you can specify how the activity should
|
|
associate with a task using the <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>
|
|
element's <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
|
|
launchMode}</a> attribute.</p>
|
|
|
|
<p>The <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
|
|
launchMode}</a> attribute specifies an instruction on how the activity should be launched into a
|
|
task. There are four different launch modes you can assign to the
|
|
<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code>
|
|
attribute:</p>
|
|
|
|
<dl>
|
|
<dt>{@code "standard"} (the default mode)</dt>
|
|
<dd>Default. The system creates a new instance of the activity in the task from
|
|
which it was started and routes the intent to it. The activity can be instantiated multiple times,
|
|
each instance can belong to different tasks, and one task can have multiple instances.</dd>
|
|
<dt>{@code "singleTop"}</dt>
|
|
<dd>If an instance of the activity already exists at the top of the current task, the system
|
|
routes the intent to that instance through a call to its {@link
|
|
android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a new instance of the
|
|
activity. The activity can be instantiated multiple times, each instance can
|
|
belong to different tasks, and one task can have multiple instances (but only if the
|
|
activity at the top of the back stack is <em>not</em> an existing instance of the activity).
|
|
<p>For example, suppose a task's back stack consists of root activity A with activities B, C,
|
|
and D on top (the stack is A-B-C-D; D is on top). An intent arrives for an activity of type D.
|
|
If D has the default {@code "standard"} launch mode, a new instance of the class is launched and the
|
|
stack becomes A-B-C-D-D. However, if D's launch mode is {@code "singleTop"}, the existing instance
|
|
of D receives the intent through {@link
|
|
android.app.Activity#onNewIntent onNewIntent()}, because it's at the top of the stack—the
|
|
stack remains A-B-C-D. However, if an intent arrives for an activity of type B, then a new
|
|
instance of B is added to the stack, even if its launch mode is {@code "singleTop"}.</p>
|
|
<p class="note"><strong>Note:</strong> When a new instance of an activity is created,
|
|
the user can press the <em>Back</em> button to return to the previous activity. But when an existing
|
|
instance of
|
|
an activity handles a new intent, the user cannot press the <em>Back</em> button to return to the
|
|
state of
|
|
the activity before the new intent arrived in {@link android.app.Activity#onNewIntent
|
|
onNewIntent()}.</p>
|
|
</dd>
|
|
|
|
<dt>{@code "singleTask"}</dt>
|
|
<dd>The system creates a new task and instantiates the activity at the root of the new task.
|
|
However, if an instance of the activity already exists in a separate task, the system routes the
|
|
intent to the existing instance through a call to its {@link
|
|
android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a new instance. Only
|
|
one instance of the activity can exist at a time.
|
|
<p class="note"><strong>Note:</strong> Although the activity starts in a new task, the
|
|
<em>Back</em> button still returns the user to the previous activity.</p></dd>
|
|
<dt>{@code "singleInstance"}.</dt>
|
|
<dd>Same as {@code "singleTask"}, except that the system doesn't launch any other activities into
|
|
the task holding the instance. The activity is always the single and only member of its task;
|
|
any activities started by this one open in a separate task.</dd>
|
|
</dl>
|
|
|
|
|
|
<p>As another example, the Android Browser application declares that the web browser activity should
|
|
always open in its own task—by specifying the {@code singleTask} launch mode in the <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element.
|
|
This means that if your application issues an
|
|
intent to open the Android Browser, its activity is <em>not</em> placed in the same
|
|
task as your application. Instead, either a new task starts for the Browser or, if the Browser
|
|
already has a task running in the background, that task is brought forward to handle the new
|
|
intent.</p>
|
|
|
|
<p>Regardless of whether an activity starts in a new task or in the same task as the activity that
|
|
started it, the <em>Back</em> button always takes the user to the previous activity. However, if you
|
|
start an activity that specifies the {@code singleTask} launch mode, then if an instance of
|
|
that activity exists in a background task, that whole task is brought to the foreground. At this
|
|
point, the back stack now includes all activities from the task brought forward, at the top of the
|
|
stack. Figure 4 illustrates this type of scenario.</p>
|
|
|
|
<img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" />
|
|
<p class="img-caption"><strong>Figure 4.</strong> A representation of how an activity with
|
|
launch mode "singleTask" is added to the back stack. If the activity is already a part of a
|
|
background task with its own back stack, then the entire back stack also comes
|
|
forward, on top of the current task.</p>
|
|
|
|
<p>For more information about using launch modes in the manifest file, see the
|
|
<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>
|
|
element documentation, where the {@code launchMode} attribute and the accepted values are
|
|
discussed more.</p>
|
|
|
|
<p class="note"><strong>Note:</strong> The behaviors that you specify for your activity with the <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> attribute
|
|
can be overridden by flags included with the intent that start your activity, as discussed in the
|
|
next section.</p>
|
|
|
|
|
|
|
|
<h4 id="#IntentFlagsForTasks">Using Intent flags</h4>
|
|
|
|
<p>When starting an activity, you can modify the default association of an activity to its task
|
|
by including flags in the intent that you deliver to {@link
|
|
android.app.Activity#startActivity startActivity()}. The flags you can use to modify the
|
|
default behavior are:</p>
|
|
|
|
<p>
|
|
<dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt>
|
|
<dd>Start the activity in a new task. If a task is already running for the activity you are now
|
|
starting, that task is brought to the foreground with its last state restored and the activity
|
|
receives the new intent in {@link android.app.Activity#onNewIntent onNewIntent()}.
|
|
<p>This produces the same behavior as the {@code "singleTask"} <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> value,
|
|
discussed in the previous section.</p></dd>
|
|
<dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt>
|
|
<dd>If the activity being started is the current activity (at the top of the back stack), then
|
|
the existing instance receives a call to {@link android.app.Activity#onNewIntent onNewIntent()},
|
|
instead of creating a new instance of the activity.
|
|
<p>This produces the same behavior as the {@code "singleTop"} <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> value,
|
|
discussed in the previous section.</p></dd>
|
|
<dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt>
|
|
<dd>If the activity being started is already running in the current task, then instead
|
|
of launching a new instance of that activity, all of the other activities on top of it are
|
|
destroyed and this intent is delivered to the resumed instance of the activity (now on top),
|
|
through {@link android.app.Activity#onNewIntent onNewIntent()}).
|
|
<p>There is no value for the <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a>
|
|
attribute that produces this behavior.</p>
|
|
<p>{@code FLAG_ACTIVITY_CLEAR_TOP} is most often used in conjunction with {@code
|
|
FLAG_ACTIVITY_NEW_TASK}. When used together, these flags are a way of locating an existing activity
|
|
in another task and putting it in a position where it can respond to the intent. </p>
|
|
<p class="note"><strong>Note:</strong> If the launch mode of the designated activity is {@code
|
|
"standard"}, it too is removed from the stack and a new instance is launched in its place to handle
|
|
the incoming intent. That's because a new instance is always created for a new intent when the
|
|
launch mode is {@code "standard"}. </p>
|
|
</dd>
|
|
</dl>
|
|
|
|
|
|
|
|
|
|
|
|
<h3 id="Affinities">Handling affinities</h3>
|
|
|
|
<p>The <em>affinity</em> indicates which task an activity prefers to belong to. By default, all the
|
|
activities from the same application have an affinity for each other. So, by default, all
|
|
activities in the same application prefer to be in the same task. However, you can modify
|
|
the default affinity for an activity. Activities defined in
|
|
different applications can share an affinity, or activities defined in the same application can be
|
|
assigned different task affinities.</p>
|
|
|
|
<p>You can modify the affinity for any given activity with the <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> attribute
|
|
of the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>
|
|
element.</p>
|
|
|
|
<p>The <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
|
|
attribute takes a string value, which must be unique from the default package name
|
|
declared in the <a href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code
|
|
<manifest>}</a> element, because the system uses that name to identify the default task
|
|
affinity for the application.</p>
|
|
|
|
<p>The affinity comes into play in two circumstances:</p>
|
|
<ul>
|
|
<li>When the intent that launches an activity contains the {@link
|
|
android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag.
|
|
|
|
<p>A new activity is, by default, launched into the task of the activity
|
|
that called {@link android.app.Activity#startActivity startActivity()}. It's pushed onto the same
|
|
back stack as the caller. However, if the intent passed to {@link
|
|
android.app.Activity#startActivity startActivity()} contains the {@link
|
|
android.content.Intent#FLAG_ACTIVITY_NEW_TASK}
|
|
flag, the system looks for a different task to house the new activity. Often, it's a new task.
|
|
However, it doesn't have to be. If there's already an existing task with the same affinity as the
|
|
new activity, the activity is launched into that task. If not, it begins a new task.</p>
|
|
|
|
<p>If this flag causes an activity to begin a new task and the user presses the <em>Home</em> button
|
|
to leave
|
|
it, there must be some way for the user to navigate back to the task. Some entities (such as the
|
|
notification manager) always start activities in an external task, never as part of their own, so
|
|
they always put {@code FLAG_ACTIVITY_NEW_TASK} in the intents they pass to {@link
|
|
android.app.Activity#startActivity startActivity()}. If you have an activity that can be invoked by
|
|
an external entity that might use this flag, take care that the user has a independent way to get
|
|
back to the task that's started, such as with a launcher icon (the root activity of the task
|
|
has a {@link android.content.Intent#CATEGORY_LAUNCHER} intent filter; see the <a
|
|
href="#Starting">Starting a task</a> section below).</p>
|
|
</li>
|
|
|
|
<li>When an activity has its <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code
|
|
allowTaskReparenting}</a> attribute set to {@code "true"}.
|
|
<p>In this case, the activity can move from the task it starts to the task it has an affinity
|
|
for, when that task comes to the foreground.</p>
|
|
<p>For example, suppose that an activity that reports weather conditions in selected cities is
|
|
defined as part of a travel application. It has the same affinity as other activities in the same
|
|
application (the default application affinity) and it allows re-parenting with this attribute.
|
|
When one of your activities starts the weather reporter activity, it initially belongs to the same
|
|
task as your activity. However, when the travel application's task comes to the foreground, the
|
|
weather reporter activity is reassigned to that task and displayed within it.</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p class="note"><strong>Tip:</strong> If an {@code .apk} file contains more than one "application"
|
|
from the user's point of view, you probably want to use the <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
|
|
attribute to assign different affinities to the activities associated with each "application".</p>
|
|
|
|
|
|
|
|
<h3 id="Clearing">Clearing the back stack</h3>
|
|
|
|
<p>If the user leaves a task for a long time, the system clears the task of all activities except
|
|
the root activity. When the user returns to the task again, only the root activity is restored.
|
|
The system behaves this way, because, after an extended amount of time, users likely have abandoned
|
|
what they were doing before and are returning to the task to begin something new. </p>
|
|
|
|
<p>There are some activity attributes that you can use to modify this behavior: </p>
|
|
|
|
<dl>
|
|
<dt><code><a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code>
|
|
</dt>
|
|
<dd>If this attribute is set to {@code "true"} in the root activity of a task,
|
|
the default behavior just described does not happen.
|
|
The task retains all activities in its stack even after a long period.</dd>
|
|
|
|
<dt><code><a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt>
|
|
<dd>If this attribute is set to {@code "true"} in the root activity of a task,
|
|
the stack is cleared down to the root activity whenever the user leaves the task
|
|
and returns to it. In other words, it's the opposite of <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code
|
|
alwaysRetainTaskState}</a>. The user always returns to the task in its
|
|
initial state, even after a leaving the task for only a moment.</dd>
|
|
|
|
<dt><code><a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code>
|
|
</dt>
|
|
<dd>This attribute is like <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a>,
|
|
but it operates on a
|
|
single activity, not an entire task. It can also cause any activity to go
|
|
away, including the root activity. When it's set to {@code "true"}, the
|
|
activity remains part of the task only for the current session. If the user
|
|
leaves and then returns to the task, it is no longer present.</dd>
|
|
</dl>
|
|
|
|
|
|
|
|
|
|
<h3 id="Starting">Starting a task</h3>
|
|
|
|
<p>You can set up an activity as the entry point for a task by giving it an intent filter with
|
|
{@code "android.intent.action.MAIN"} as the specified action and {@code
|
|
"android.intent.category.LAUNCHER"} as the specified category. For example:</p>
|
|
|
|
<pre>
|
|
<activity ... >
|
|
<intent-filter ... >
|
|
<action android:name="android.intent.action.MAIN" />
|
|
<category android:name="android.intent.category.LAUNCHER" />
|
|
</intent-filter>
|
|
...
|
|
</activity>
|
|
</pre>
|
|
|
|
<p>An intent filter of this kind causes an icon and label for the
|
|
activity to be displayed in the application launcher, giving users a way to launch the activity and
|
|
to return to the task that it creates any time after it has been launched.
|
|
</p>
|
|
|
|
<p>This second ability is important: Users must be able to leave a task and then come back to it
|
|
later using this activity launcher. For this reason, the two <a href="#LaunchModes">launch
|
|
modes</a> that mark activities as always initiating a task, {@code "singleTask"} and "{@code
|
|
"singleInstance"}, should be used only when the activity has an {@link
|
|
android.content.Intent#ACTION_MAIN}
|
|
and a {@link android.content.Intent#CATEGORY_LAUNCHER}
|
|
filter. Imagine, for example, what could happen if the filter is missing: An intent launches a
|
|
{@code "singleTask"} activity, initiating a new task, and the user spends some time working in
|
|
that task. The user then presses the <em>Home</em> button. The task is now sent to the background
|
|
and is
|
|
not visible. Now the user has no way to return to the task, because it is not represented in the
|
|
application launcher.
|
|
</p>
|
|
|
|
<p>For those cases where you don't want the user to be able to return to an activity, set the
|
|
<code><a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> element's
|
|
<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code
|
|
finishOnTaskLaunch}</a> to {@code "true"} (see <a
|
|
href="#Clearing">Clearing the stack</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>
|
|
-->
|