Joanna Smith
Google Developers
Published in
6 min readMay 12, 2016

--

Dominating the Overview Screen

Nearly everyone is familiar with the “recents menu” (technically called the Overview screen). Probably because it has a guaranteed button dedicated to letting users switch context with ease. But some apps have more than one card in this Overview screen, which can make them seem special.

But they’re not, actually. Any app can have multiple cards here. And the system permits more than one task per app to be listed at once. But that means we need to take a moment to discuss tasks. (Or you can read Ian Lake’s blog post to learn all about the task stack.)

A brief introduction to tasks

Despite what it looks like, the Overview screen is not actually a list of the recent apps a user has used. Rather, it is a list of tasks. Tasks are how your app can distinguish between disparate elements, where a user might want to switch between each piece. For example, consider an email app with a primary task for the inbox and a separate task for composing a new email. If both are listed in the recents menu, the user can easily reference back to the existing email when drafting their response. This is a beautiful use of tasks.

With the introduction of the N preview, we have now been exposed to the multi-window world. And this actually presents a perfect opportunity to identify what should be a separate task. Because in the multi-window world, each task will have its own window. So, if two elements of your app should logically exist side-by-side — that’s a moment for tasks.

So, now that you understand a bit more about tasks, the next logical question is what this has to do with the Overview screen.

Tasks as Concurrent Documents

We call multiple tasks “concurrent documents” and concurrent documents is what you see when you see two or more cards in the recents menu, all from one app. Since Android 5.0 allows more than one task from each app to appear in the Overview screen, it’s useful to know how to leverage concurrent documents in your own app. Especially because doing so can make it easier for users to do things and that will make users love you.

We call it “concurrent” because your app is multi-tasking here, as the user interacts with multiple parts of your app at once. And we refer to these separate instances as “documents” because we didn’t have a better way to say “anything that you create that lives separately from the rest of your app.”

That “document” could actually be a document, in a text editor. But it could also be that draft email we discussed earlier, or a tab in a browser, or even a specific conversation view within a messaging app. Your imagination is your only limit here.

So, the first step in creating concurrent documents is identifying what should logically exist independently. To that end, multi-window really helps distinguish good cases for concurrent documents. Any time you would want to see two Activities side-by-side, those activities would have to be separate tasks. So use this as your guiding principle when identifying elements to separate out. Could the user benefit from a side-by-side view?

How to add a task

To add a task to the Overview screen, you have two approaches to choose from: using a manifest attribute to specify the default behavior for an Activity or using a flag to specify the document behavior for an Intent dynamically.

Using a manifest attribute

If you prefer to only specify the document behavior once, you can set a default behavior for an entire Activity in your AndroidManifest.xml file. The android:documentLaunchMode attribute has four possible values:

  • intoExisting reuses a previous document for this new task, perhaps even replacing an existing task in the document.
  • always will create a new document for the task, every time.
  • none creates the task in the same window as the current activity, aka on the same stack.
  • never serves to override any specified flags and keep the task in the current stack.

Using Intent Flags

If you decide you want to determine the document status on a flexible basis by using flags, then it’s time to become familiar with the addFlags() method when building your Intent. (In case you weren’t already.) There are two flags you need to be aware of when dealing with concurrent documents.

FLAG_ACTIVITY_NEW_DOCUMENT is the equivalent of specifying intoExisting for the manifest attribute. It tells the system to treat this next task as its own window in the Overview screen. However, if there is an existing task with the same base component name and data Uri, the system will reuse it. This means your new document could be replacing an existing document. However, you can override this default behavior. If you always want the system to create a brand new task, you can also add the FLAG_ACTIVITY_MULTIPLE_TASK, which is the equivalent of specifying always for the manifest attribute.

Note: When using the flags approach, the task is automatically removed from the overview screen when the activities are destroyed. So, for a perfect match between flags and the always attribute, you also need to add FLAG_ACTIVITY_RETAIN_IN_RECENTS.

In multi-window mode, this gets even better as you can use FLAG_ACTIVITY_LAUNCH_ADJACENT in conjunction with FLAG_ACTIVITY_NEW_DOCUMENT to hint to the system that the task should be launched alongside the existing task. Fortunately, in non-multi-window mode, this flag provides a hint that the system simply ignores.

This approach may look something like the example below, where you are constructing your Intent with its extras. But, before calling startActivity, you’re also adding the flag for a new document, and perhaps even the flag for multiple tasks (depending on your decision-making process there).

Intent newDocumentIntent =
new Intent(this, NewDocumentActivity.class);
newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, counter);
newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
if (mMultipleTasksCheckbox.isChecked()) {
newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
}
startActivity(newDocumentIntent);

Between flags and the attribute, you’re accomplishing the same goal. But where an attribute only needs to be specified once for the activity, a flag will need to be added to every Intent. So you’ll want to choose a code path based on the variability of your Activity’s use case.

Getting fancy with concurrent documents

The end goal here is to place your app in a position to be helpful when the user checks that recents menu. Adding your tasks to the list is only the beginning. There are several other ways you can customize and control that experience.

To avoid cluttering the recents screen, you can set the maximum number of tasks from your app that can appear in that screen. To do this, set the <application> attribute android:maxRecents. The current maximum that can be specified is 50 tasks per user (25 for low RAM devices).

To remove a task entirely, you can use finishAndRemoveTask(). And if you’re not quite ready to let go yet, tasks can persist across reboots. So if you’d like to retain one or all of your tasks, specify that in the android:persistableMode attribute. (But make sure you’re properly saving your activity state.)

And, fun fact: you can even change the look of an activity in the recents screen, with a custom color, label, and icon. Just call setTaskDescription() to get each task to look exactly right and — most importantly — be clear to the user.

What’s next?

With all of these great flags and manifest attributes for concurrent document behavior, your app will be dominating that recents menu in no time! Just, you know, be sure that domination is thoughtful and useful to a user. Because you don’t want to go crazy and get yourself uninstalled. Use your newfound skills wisely in order to #BuildBetterApps.

Follow the Android Development Patterns Collection for more!

--

--

Joanna Smith
Google Developers

Developer Advocate for G Suite wanting to help get G Suite to work for you