Android SDK: Activities & Lifecycle
We are learning to develop Android apps from scratch in this series. We already encountered the basics of developing, running, and working with your apps in Eclipse, as well as looking at the essential elements in any app project. In this tutorial, we will explore the Activity life cycle, which is one of the key aspects of Android you need to understand to start making apps. We will look at the Activity life cycle for a typical app launched from the device menu in this tutorial.
The Activity life cycle doesn't just come into play when the user runs your app, it also affects what happens when the user switches away from and back to your app. When you develop an app, you need to remember that the user will typically navigate between it and other apps during execution. An app can either be in the foreground or the background depending on what the user is doing. Your apps need to be able to cope with this, saving and restoring data when necessary. Keep in mind that the process is slightly different for some apps, like widgets.
1. Callback Methods
To control what happens when your Activity is in different states, for example when the user navigates away from or back to it, you can implement various methods. These are the Activity life cycle callback methods. Android calls these methods when your Activity enters each state, so you can take steps to ensure the app continues to function, does not lose data, and does not use unnecessary resources when the user is not interacting with it. Each callback method puts your app in one of a range of possible states.
If you've ever programmed Java applications before, you know that Android apps are launched differently. Rather than using a main method, when your app is launched the onCreate method of the main Activity class executes. Remember that we specified the class in the Manifest as the main launcher Activity. The onCreate method is the first of the Activity callbacks, which executes when the user launches your app. The onCreate method puts your app in the Created state.
The diagram in the Developer Guide provides an intuitive representation of the life cycle, callback methods, and states. The Resumed state, which represents your app running as the user interacts with it, follows the onResume method. Various callback methods take your app towards and away from the Resumed state, starting and stopping it.
For most apps you only need to implement some of the callback methods, at the very least onCreate. However, understanding all of the callbacks and states will help you to grasp what happens on the Android system when your app runs and stops running. In general, you need to implement whichever callbacks that let the user resume your app from where they left off, and if they navigate away and back, save any data you need to persist and prevent your app from using resources unnecessarily.
There are five states your app can be in: Created, Started, Resumed, Paused, and Stopped. Seven callback methods transition into and out of these states: onCreate, onStart, onRestart, onResume, onPause, onStop, and onDestroy. These methods take your app between the possible states, in some cases very quickly. In general you can think of your app as being either resumed, paused, or stopped at any time, since the other states are transitory.
When your app is running and the user is interacting with it, it is in the Resumed state. Your app goes into Paused state when another Activity is in the foreground but only partially hides it; the user can't interact with your app in this state. When your app is completely in the background and the user can't see or interact with it at all, it is in the Stopped state. Here the Activity can retain data in this state but can't execute.
2. Moving Towards Resumed
As we know, the main Activity starts when the app is launched, with the onCreate method executing, letting you prepare the Activity UI and any data items you need throughout the class. Most apps you build will have more than one Activity in them, with the other Activities launched on user interaction with the app. You can launch one Activity from another using the Intent class as in the following example code:
Intent aboutIntent = new Intent(this, About.class); startActivity(aboutIntent);
This represents another Activity class named "About" in your app package. You can create a new Activity in Eclipse by selecting your source package and choosing "File", "New", "Class", and selecting the Android Activity class as superclass. Remember that each Activity must be listed in your Manifest. You can also pass data between Activities using the Intent class.
When any Activity runs, the onCreate method executes, so you can treat other Activity classes in your apps similarly to the main Activity except for the way you list them in the Manifest. You can create a layout file for each Activity and set it using the same technique you used for the main Activity.
After the onCreate method of an Activity executes, the onStart and onResume methods execute, placing the Activity in Resumed state, passing through Created and Started along the way.
Your Activities can reach the Resumed state in more than one way, not just when the app is launched. If your Activity is Paused or Stopped, it can be brought back into the foreground without the onCreate method being called again. If your app is brought back into the Resumed state from the Paused state, the Activity onResume method executes. If the app is brought back from Stopped state, onRestart executes, followed by onStart and onResume.
3. Moving Towards Destroyed
When your app is either exited or hidden, it moves from Resumed towards being destroyed. The onPause method takes your Activity from its normal running Resumed state to Paused. In onPause, you should stop any ongoing resource-hungry tasks such as animations, sensor handling, and broadcast receivers. If onPause executes, there is a good chance onStop is about to execute too since the user is possibly navigating away from your app. You can also use the method to save data, although in general this is best done in onStop.
As we mentioned above, your Activity can go back from Paused to Resumed via the onResume method. This means that you can use onResume to restore anything you stopped or released in onPause. However, bear in mind that onResume also executes in other cases, such as when the app is launched.
After onPause, onStop executes if the app enters Stopped state. From here, onRestart, onStart, and onResume can still take it back to Resumed. In onStop you should carry out any data saving operations you need, such as writing to databases. Make sure you release any resources your app is using in onStop to prevent any memory leaks if your app is destroyed.
The system saves certain data items when your app resumes after it is stopped, such as what is displayed in the Views. When an Activity moves from Stopped back to Resumed, the onRestart, onStart, and onResume methods all execute. However, onStart and onResume execute in other cases, such as when the app is launched. The onRestart method only executes when the app is coming back from Stopped state, so you can use it to reinstate anything you did in onStop.
If your app is about to completely finish, like with the instance of your current Activity removed from the system, onDestroy executes. Although this is the last method to execute before your Activity disappears completely, you should not typically use it to clean up. You should generally use onStop or onPause for this. One exception to this is where a background thread is running, in which case you should stop it in onDestroy.
After onDestroy executes, if the user navigates back to your app Activity the onCreate method executes again. In general, you can assume that onPause and onStop will execute before onDestroy. However, if you explicitly call the finish method to end an Activity, only onDestroy executes.
In many cases, you don't need to worry about most of the life cycle callbacks in your apps at all, since you can retain data using the onCreate method parameter. The Bundle parameter to your Activity onCreate method automatically saves View information as we mentioned above. However, you can also use the object to save additional data, such as variables you update as the user interacts with your app. To do this, you can implement the onSaveInstanceState method in an Activity class, writing key value pairs of data you can then retrieve in onCreate.
The various states and callback methods in Android Activities can be the source of much confusion when you start to learn how to develop apps for the platform. However, in most cases you only need to implement a minimal number of the methods to keep your apps functional and behaving the way users expect. In the next part of the series, we will look at some of the common Android classes you are likely to find useful in your first apps. After that we will look at the Android sample code, what you need to know about releasing your apps, and some other suggestions for future learning.