Activities, Tasks and Intents, Oh My!

Whenever you read about Android development, you’ll see the word Activity pop up all the time. In this article, we’ll explain what Activities are, and how they relate to Tasks, Processes and the Back Stack running on the phone.

Activities

An activity is a visual component that you see on a screen, with some associated logic to manage life cycle and navigation. An application will generally consist of several activities. When you move from screen to screen, generally you are changing Activities, replacing what is on the screen with the new contents and controller.

Each activity is defined as a subclass of android.app.Activity, and must be declared in your manifest file, along with a declaration of how the activity can be started. The activity also has a lifecycle, responding to the following state machine:

Android Intents Figure 1

Activity State Machine

When an activity is on screen, it is running (green in the diagram). When Android changes activities, it will be paused. It is the developer’s responsibility to stop any CPU hungry tasks (e.g. Animation, Graphics) that are running when the onPause() method is called. Android may also request that an Activity be stopped because it wants to recover memory. When this happens, the activity may be stopped. As before, it is the developer’s responsibility to release any memory it can when it is sent the onStop() method. Finally, when the application is shut down, the onDestroy() method is called. There are also corresponding onCreate(), onStart() and onResume() methods that are used when the activity is progressively brought to its running state.

Activities may be started, or re-started at any time. It is important that the developer puts the right code in his activity to save any state information. As an example, by default, Android will re-create an Activity when the screen rotates, to allow the activity to use a different layout and components. It is possible to override this, but it serves as an example. Developers should put code in the onStart() and onStop() methods to save any state required.

Linking Activities Together with the Back Stack

Most applications will consist of ore than one screen, and Android has a very strong back mechanism through its use of a dedicated back button. It implements this using a Back Stack. When you click on an application in the home app, Android will start a back stack, and push on the home activity. If the application then navigates to another Activity, the appropriate lifecycle events are called and then it is pushed onto the stack, becoming the topmost (active) activity.

Android Intents Figure 2

Android Back Stack

So far, this all sounds very straight forward, right? Every phone OS these days works in this fashion. Where Android is a little different is that a back stack can contain activities from different applications, grouped into something which is called a Task.

It is possible for one app to launch an activity in another application, using something called an Intent (which we will discuss later). This allows different applications to collaborate, but without having to know too much about each other. As an example, you might want to send an email from your application when the user clicks on a “Feedback” button. When this happens, Android pushes the composer activity from the Gmail application onto the back stack for the task, and the user types their message. When they finish (or press back), Android pops off the gmail activity and returns you to the next activity down, which will be your application. This makes it look like the applications have worked together as a coherent … well Task… when in fact they are completely independent.

Android Intents Figure 3

Mixing Applications in a Task

It is also possible to have more than one Task active at one time. Lets say you load up an application and drill down a few activities to what you want, then press the Home button, and start another application. Android remembers the state of where you were before in a Task. It then starts a new Task for your new application, which you could drill down some more. You are now free to go back out to switch between these two tasks, each time returning to exactly where you were before, thanks to the remembered Task and its back stack.

By default, Android will forget Tasks after a while if you don’t return to them. The rationale is that if you haven’t used a task for a period then you’ve lost interest in it and it can be shut down. This explains why if you exit say your web browser but go back to it soon after then you return to the last page you were on, but if you come back a few days later it might take you back to your home page instead. This is all managed for you automatically by Android.

Intents: Navigating between Activities (Amongst Other Things).

We mentioned earlier that navigation between activities is managed by Intents. An Intent is a type of message that applications broadcast through the Android OS to interested parties on the phone. Applications then register themselves as listeners for these Intent events using the Android manifest file, and take action accordingly. Used correctly they can be very powerful.

The simplest example of navigating between Activities within an application is to use an Explicit Intent. Using this method, a developer can specify the specific Activity class that they wish to start (for example using the startActivity() method in Activity). This is very straightforward though, and well documented in the Android developer docs. Lets look instead at how one could send an Email using an intent. Here’s a snippet from one of my applications, which makes it easy for users to send diagnostic logs to me:

Intent sendIntent = new Intent(Intent.ACTION_SEND);
// Add attributes to the intent
sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Log dump from NodeDroid");
sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "android-logs@8bitcloud.com" });
sendIntent.putExtra(Intent.EXTRA_TEXT, "");
sendIntent.setType("application/zip");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(dumpFile));

startActivity(Intent.createChooser(sendIntent, "Email:"));

In this code sample, I’ve created an intent, and given it an action (Intent.ACTION_SEND) and set some extra fields to specify who the email should go to, the subject, and the file attachment. Finally, I call startActivity() to launch the intent. When run, the intent is broadcast to the Android OS, which checks to see which applications can respond to it. If more than one application can respond (which would be quite common in this case), the OS presents the user with a choice of application to handle the intent, and the option as choosing that as the default to use going forward. When a choice is made, the activity is started and the compose screen will be shown.

When writing an application, developers should choose how they will structure their intents so that they can be used by other applications. For example, you might be writing a contact list application. By choosing the right action name and passing the contact ID as additional data in the intent, you make it possible for other applications to load up contact information for a user, rather than your app being a closed box, only accessible to itself.

The Wrap Up

In this article we have explained the way that Android puts together its navigation through using Activities and Tasks. This is all bound together by Android’s powerful Intent system, making it possible to create applications that collaborate on the phone, providing a consistent and intuitive interface for users to use. There are a number of concepts to pick up around Tasks and Activities when developing with Android, but once you’ve got the hang of them it becomes very easy to produce applications that work well with the rest of the system. Personally, I think this is one of the most compelling differentiators for the Android platform.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Tracy

    You can go from onPause() to killed so if you really like your data, save it in onPause() or onSaveInstanceState(Bundle).

    Except, starting with HONEYCOMB the semantics have been changed to so that you are not killable until after onStop().

    WELCOME TO THUNDERDOME!

    http://developer.android.com/reference/android/app/Activity.html

  • tiggsy

    Reading this on an android phone entailed a lot of side to side scrolling regardless of orientation