Android Activities and Tasks series – Intent flags

The previous post of the Activities and Tasks series gave an introduction to the concepts behind activities and tasks. We have seen that activities correspond to visible screens in the UI, that activities are grouped as stacks within tasks, and tasks are sent to the background and foreground as atomic units. In this post of the series, we focus on Android’s intent concept and address the following questions:

  1. What are intents?
  2. How do we use them to launch activities?
  3. What options (flags) does Android provide to customize this launch? (e.g. in terms of target task or activity instance creation)


In order to ease understanding of intents and their various flags, akquinet Modular and Mobile Solutions provides an Android application to experiment with intent flags. With it, you can start different types of activities, specifying the intent flags you want to pass, and examine the effects. Install it by pointing your Android browser to this URL.

Intents and activity launching

An intent is a data structure containing a description of a to-be-performed operation. This operation primarily consists of an action and of data to operate on, although there are various optional parameters to describe the operation in more detail. Technically speaking, this action is just a constant, either a pre-defined one from Android, like ACTION_VIEW or ACTION_EDIT, or a custom one that we can define ourselves.

An intent is always handled by an Android component, namely an activity, a service or a broadcast receiver. In this blog post series, we will focus on activities as intent handlers. For our purposes, an intent is used to launch an activity.

To create an intent and launch an activity with it, we can write the following code within our caller activity:

Intent intent = new Intent(Intent.ACTION_VIEW,
    Uri.parse("http://www.akquinet.com/")
startActivity(intent);

In this example, we give two parameters to the Intent constructor: The action to be performed (here view) and the corresponding data (here a web page URL). Then, we simply pass the Intent object to startActivity(Intent). Basically, what we do here is telling Android that we want to view the akquinet homepage. Android will look for activities capable of handling that intent, which in this case is a web browser activity, and start it. Note that any activity can be declared capable of handling certain intent types by defining intent filters in the application’s AndroidManifest.xml file.

Instead of letting Android choose a suitable activity, an intent may also name the to-be-launched target activity explicitly by specifying the target activity’s class, like so:

Intent intent = new Intent(this, MyActivity.class);
startActivity(intent);

When run, this code snippet has the following consequences:

  1. A new instance of MyActivity is created
  2. The instance is pushed on top of the current task’s stack, which is the one the calling activity is in.
  3. The activity is started and brought to the foreground.

Customizing the launch of activities via intent flags

The described behavior can be modified by specifying intent flags on the intent instance before passing the intent to startActivity(Intent), for example:

intent.addFlag(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

This will bring an existing instance of the called activity type present in the current stack to the foreground (if there is such an instance) instead of creating a new instance. Android 2.0 defines various intent flags, which are now explained in more detail.

FLAG_ACTIVITY_BROUGHT_TO_FRONT

This flag is set by the system as an indication that an existing activity with launch mode singleTask has been called and reused. Activity launch modes are discussed in more detail in the next blog post.

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
Bringing a task to foreground after using flag CLEAR_WHEN_TASK_RESET

This flag marks the called activity and all activities put on top of it to be cleared (removed from the stack) when the task is reset. This reset is performed as soon as the task is brought to the foreground using FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, which is always set by the system when the user resumes a task from the home screen, the main menu or the list of recently started activites.

You can use this to define a point in the task stack from where all started activities should be “forgotten” once the task is sent to the background.

FLAG_ACTIVITY_CLEAR_TOP
Using flag CLEAR_TOP to launch an activity

If there is already an instance of the called activity type present in the stack, then this instance is brought to the foreground instead of creating a new instance. Also, all activities in the stack that reside on top of that instance are cleared from the stack. For example, assuming that the current activity stack is ABCDE, launching an activity of type C will clear activities D and E from the task and result in the stack ABC.

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

Normally, when launching an activity in a new task, the target activity is shown in the list of recently launched activities (accessible via long press of the home button). For example, this is the case when launching the browser from your activity to render a web page. Using this flag, we can suppress that behavior, effectively excluding the target activity from the list of recently launched activities.

FLAG_ACTIVITY_FORWARD_RESULT

By default, in order for an activity B to be able to propagate a result back to the calling activity A, A has to use the method startActivityForResult(Intent) instead of method startActivity(Intent) to start B. When B defines its result via setResult(int resultCode) and finishes, the callback method onActivityResult() is called on A where the result can be retrieved.

Resulting forwarding with Flag FORWARD_RESULT

Suppose now that B calls another activity C, which defines the result, and we want to forward that result back to A. In order to avoid having to pass results manually from B to A, Android provides this flag.
In our example, this means that B calls C, specifying the forward flag and using startActivity(Intent). C may then define a result, which is forwarded back to A automatically once C and B are finished. The callback method onActivityResult() is called on A but not called on the intermediate activity B as B only forwards the result instead of explicitly handling it.
Note that the flag may only be used in conjunction with startActivity(Intent), not with startActivityForResult(Intent), because an activity using the latter method marks the end of a forwarding chain and should handle the result in its callback method.

FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY

This flag is set by the system as an indication that an activity has been launched from the list of recently launched activities.

FLAG_ACTIVITY_MULTIPLE_TASK
This flag has no effect unless used in conjunction with FLAG_ACTIVITY_NEW_TASK. If used together, a new task is always created and a new instance of the called activity type becomes the first (and at that time, the only) element of that task.

FLAG_ACTIVITY_NEW_TASK

If this flag is used on its own (without FLAG_ACTIVITY_MULTIPLE_TASK), a new task is only created if there is not already a task present that the target activity has an affinity for (task affinities are examined more closely in the next blog post). If such a task already exists, the activity is put into that task instead of creating a new one.
As all activities specified within the same application have a default affinity to remain in the same task (this can be customized), starting an activity defined in the same application as the calling activity using this flag will not create a new task, unless FLAG_ACTIVITY_MULTIPLE_TASK is specified as well.

FLAG_ACTIVITY_NO_ANIMATION

Introduced with Android 2.0, this flag disables the usual animation accompanied by an activity transition. For example, this can be used to call an activity that itself launches another activity without further user interaction, resulting in only one transition animation to be shown instead of two.

FLAG_ACTIVITY_NO_HISTORY

This flag implies that the called activity is not kept in the task’s stack. When navigating away, the user cannot return to it. For example, this is useful to launch activities that perform an immediate dispatch to another activity. This activity is consequently skipped if the user presses the back button as it is not kept in the stack.

FLAG_ACTIVITY_NO_USER_ACTION

This flag may be used as an indication that the activity transition is not an action directly performed by the user but rather an automatic one. For example, this is true for the call-in activity that is automatically launched when the device receives a phone call. Technically, it means that the invocation of callback method onUserLeaveHint() on the caller activity is suppressed.

FLAG_ACTIVITY_REORDER_TO_FRONT
Starting an activity with Flag REORDER_TO_FRONT

If there is already an instance of the called activity type present in the task stack, that instance is brought to the foreground while the rest of the stack is kept intact. This effectively reorders the stack. For example, assuming that the current activity stack is ABCDEF, launching an activity of type C using this flag will result in the new stack ABDEFC.

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

This flag has no effect unless the intent creates a new task or brings an existing task to the foreground. In that case, the task is reset, meaning that task affinities are applied (resulting in activities being moved from or to this task) and that, given that FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET is set as well, the task is cleared according that flag’s specification.

FLAG_ACTIVITY_SINGLE_TOP

If an instance of the target activity is already at the top of the stack, no new instance is created.

Conclusion

The akquinet Mobile and Modular Solutions provides an Android application to help you understand the effects of the intent flags. It lets you start exemplary activities using arbitrary intent flags and inspect the effects on the resulting task stack.

Intent Flags Tool - Main screen
Intent Flags Tool - Main screen
Intent Flags Tool - Selecting Flags
Intent Flags Tool - Selecting Flags

You can download the tool here. The source code is also available on github.

All described behavior not only depends on intent flags specified, but also on attributes defined on the called activity type (in AndroidManifest.xml), including task affinities and launch modes. While intent flags are specified by the caller, launch modes and affinities are properties of the callee. Those will be discussed in the next post of this series.

30 thoughts on “Android Activities and Tasks series – Intent flags

  1. Thanks for the concise information and VERY HELPFUL sample app. I’ve read a lot of blogs trying to understand activities and relationships to tasks and this is the first time everything is really starting to just “click”.

  2. Would you be willing to post the source for the tool? It’s a pretty nice teaching tool for people trying to learn Android and it would help them to be able to step through with the debugger to understand the threading model. And having the manifest/launching code would help save people a lot of effort.

  3. Thanks for the article, very helpful. You also mentioned the “next” post that explains a concept of “affinity”. Can’t find it though…

  4. I have a question that you might be able to answer;

    If you use an ACTION_VIEW intent on a url that leads to an mp3 file:


    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://somewhere.com/song.mp3");
    startActivity(intent);

    Then it will usually show the “Complete action using” little window that gives you the choice for either ‘viewing’ the url using the music player, or via the web browser.

    If you browse to the url directly using the web browser, then the ‘Complete action using’ window appears – and if you choose “Browser” then the browser will download the mp3 file –
    however, if you start an intent from your app – to view the url, as above – and choose “Browser” from the ‘Complete action using’ window – then a new empty browser opens – that does not initiate the download, and does not browse to any url!

    Do you have an idea how to make it act the same way as when browsing to it using the web browser (that starts the download)?

  5. FLAG_ACTIVITY_CLEAR_TOP description is wrong, it will create a new instance of C even if it’s on stack to avoid it from re-creating the instance you should use FLAG_ACTIVITY_SINGLE_TOP flag along with CLEAR_TOP

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s