The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.
One of the most confusing aspects of Android to deal with is the concept of tasks. Fortunately, the automatic management of tasks is almost enough to get by, without you having to do much customization. However, many apps will have needs to tailor how their app interacts with the task system, and understanding what is possible and how to do it is not easy. It is made even more complicated by changes to Android, from both engineering and design perspectives, over the years.
This chapter will attempt to untie the knot of knowledge surrounding Android’s task system, explaining why things are the way they are. However, there will be a few places where the knot turns a bit Gordian, and we will have to settle for more about “how” and less about “why” the task system works as it does.
Understanding this chapter requires that you have read the core chapters of this book.
One sample app makes heavy use of
PackageManager system service and refers in a few
places to the
Launchalot sample app profiled in that chapter.
It will be useful to establish some common definitions of terms that you will encounter, both in this chapter and in other materials that describe the task system.
So, what exactly is a “task”?
The Android developer documentation describes it as:
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.
In that sense, a task is reminiscent of a tab in a tabbed browser. As the user navigates, clicking links and submitting forms, the user advances into other Web pages. Those pages could be on the same site as they started or could be on different sites. The browser BACK button is supposed to reverse the navigation, allowing the user to return from whence they came.
The user perceives tasks mostly in the form of pressing the BACK button, using this to return to previous “screens” that they had been on previously.
Sometimes, BACK button processing is handled within a single activity,
such as when you put a dynamic fragment onto the “back stack” via
addToBackStack() on a
FragmentTransaction. Or, the activity could
onBackPressed() and do special stuff in certain scenarios.
Those are part of the user experience of pressing BACK. From the standpoint
of the task system, though, internal consumption of the BACK button presses
do not affect the task.
At the task level, the “back stack” refers to a chain of activities.
This matches the behavior of Web sites, where while pressing the browser
BACK button might trigger in-page behavior, usually it returns you to
the previous page. Similarly, while pressing BACK on an Android device
might trigger in-activity behavior, usually it triggers a call to
finish() on the foreground activity and returns control to whatever
had preceded it on the back stack.
In a tabbed Web browser, if we have several tabs open, we think of all of them as being “running”. Frequently, we do not really even think about the concept, any more than we might think about the state of tabs in an IDE other than the one that we are working in right now. However, if you have ever had some browser tab all of a sudden start playing audio, such as from a reloaded page pulling in an audio-enabled ad banner, you are well aware that tabs are “running”, while you are also “running” to try to figure out what tab is playing the audio so you can get rid of it.
However, that is the behavior on a desktop Web browser. A desktop Web browser is not subject to heap size limitations the way Android apps are. And, historically, mobile devices had less system RAM than did their desktop and notebook counterparts, though that is rapidly changing.
In Android, therefore, developers are used to the notion that their processes may be terminated, while in the background, to free up memory for other processes. This is being done to allow for more apps to deliver more value in less system RAM.
However, from a multitasking standpoint, having apps just up and vanish
is awkward. Hence, Android has the notion of “recent tasks”. These are tasks,
with their corresponding back stacks, that the user has been in “recently”.
How far back “recently” goes depends a bit on the version of Android
– there could be as few as eight items. These “recent tasks” may or may
not have a currently-running process associated with them. However,
if the user chooses to return to one of those recent tasks, and there
is no process for it, Android will seamlessly fork a fresh process, to be
able to not only start up those apps, but return the user to where they
were, in terms of UI contents (e.g., saved instance state
and in terms of back stack contents (e.g., where the user goes if the
user now presses BACK).
In a tabbed Web browser, you can navigate between different tabs in some browser-specific way. Some tabs may have the actual “tab” visible around the address bar. Some tabs might only be reachable via some sort of scrolling operation, or via a drop-down list, for people who have lots and lots of tabs open. Regardless, there is some UI means to pick the tab that you want to be viewing in the main browser area.
In Android, the “overview screen” is where the user can view the recent tasks and choose to return to one of them. Many people, including this author, refer to this as the “recent tasks list”, but apparently the official term is “overview screen”.
The way the overview screen has looked and worked has changed over the years.
In the early days of Android, long-pressing the HOME button would bring up the overview screen, with up to eight recent tasks:
Figure 672: Overview Screen, from Android 2.3.3
And… that was pretty much it.
The overall move to the holographic theme for Android brought with us a new icon, for a dedicated way to get to the overview screen:
Figure 673: Overview Screen/Recent Tasks Navigation Bar Icon, from Android 4.3
Devices that offered a navigation bar at the bottom would have this button. Devices that chose to have off-screen affordances for BACK and HOME might have a similar button for the overview screen. For those that neither had a navigation bar nor a dedicated off-screen button for the overview screen, long-pressing HOME would bring up the overview screen.
The overview screen could have more apps (15 or so) before old tasks would be dropped:
Figure 674: Overview Screen, from Android 4.3
The overview screen also added more improvements:
FLAG_SECUREto block this, and except on some emulator images
Functionally, the Android 5.x overview screen functions much like its 4.x counterpart, with the ability to see previews of tasks and remove tasks from the screen.
However, there are some differences, starting with the navigation bar icon used to bring up the overview screen:
Figure 675: Overview Screen/Recent Tasks Navigation Bar Icon, from Android 5.0
Also, the previews are larger and stacked like cards, more so than being a classically vertically-scrolling list:
Figure 676: Overview Screen, from Android 5.0
A running task is a task that has running process(es) associated with it. Recent tasks may or may not be running.
The preview of this section took that left turn at Albuquerque.
The preview of this section was lost due to a rupture in the space-time continuum.
The preview of this section was stepped on by Godzilla.
The preview of this section is presently indisposed.
The preview of this section may contain nuts.
The preview of this section was abducted by space aliens.
The preview of this section is in an invisible, microscopic font.
The preview of this section was accidentally identified as an Android 'tasty treat' by the Cookie Monster.
The preview of this section is in the process of being translated from its native Klingon.