Activities in the system are managed as an activity stack. When a new activity is started, it is placed on the top of the stack and becomes the running activity — the previous activity always remains below it in the stack, and will not come to the foreground again until the new activity exits.
An activity has essentially four states:
- If an activity in the foreground of the screen (at the top of the stack), it is active or running.
- If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent activity has focus on top of your activity), it is paused. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations.
- If an activity is completely obscured by another activity, it is stopped.
It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere.
- If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.
The following diagram shows the important state paths of an Activity. The square rectangles represent callback methods you can implement to perform operations when the Activity moves between states. The colored ovals are major states the Activity can be in.
There are three key loops you may be interested in monitoring within your activity:
- The entire lifetime of an activity happens between the first call to
onCreate(Bundle)through to a single final call to
onDestroy(). An activity will do all setup of “global” state in
onCreate(), and release all remaining resources in
onDestroy(). For example, if it has a thread running in the background to download data from the network, it may create that thread in
onCreate()and then stop the thread in
- The visible lifetime of an activity happens between a call to
onStart()until a corresponding call to
onStop(). During this time the user can see the activity on-screen, though it may not be in the foreground and interacting with the user. Between these two methods you can maintain resources that are needed to show the activity to the user. For example, you can register a
onStart()to monitor for changes that impact your UI, and unregister it in
onStop()when the user an no longer see what you are displaying. The
onStop()methods can be called multiple times, as the activity becomes visible and hidden to the user.
- The foreground lifetime of an activity happens between a call to
onResume()until a corresponding call to
onPause(). During this time the activity is in front of all other activities and interacting with the user. An activity can frequently go between the resumed and paused states — for example when the device goes to sleep, when an activity result is delivered, when a new intent is delivered — so the code in these methods should be fairly lightweight.
Your activity monitors and reacts to these events by instantiating methods that override the
Activity class methods for each event:
Called when your activity is first created. This is the place you normally create your views, open any persistent datafiles your activity needs to use, and in general initialize your activity. When calling
onCreate(), the Android framework is passed a
Bundle object that contains any activity state saved from when the activity ran before.
Called just before your activity becomes visible on the screen. Once
onStart() completes, if your activity can become the foreground activity on the screen, control will transfer to
onResume(). If the activity cannot become the foreground activity for some reason, control transfers to the
Called right after
onStart() if your activity is the foreground activity on the screen. At this point your activity is running and interacting with the user. You are receiving keyboard and touch inputs, and the screen is displaying your user interface.
onResume() is also called if your activity loses the foreground to another activity, and that activity eventually exits, popping your activity back to the foreground. This is where your activity would start (or resume) doing things that are needed to update the user interface.
Called when Android is just about to resume a different activity, giving that activity the foreground. At this point your activity will no longer have access to the screen, so you should stop doing things that consume battery and CPU cycles unnecessarily. If you are running an animation, no one is going to be able to see it, so you might as well suspend it until you get the screen back. Your activity needs to take advantage of this method to store any state that you will need in case your activity gains the foreground again—and it is not guaranteed that your activity will resume. If the mobile device you are running on runs out of memory, there is no virtual memory on disk to use for expansion, so your activity may have to make way for a system process that needs memory. Once you exit this method, Android may kill your activity at any time without returning control to you.
Called when your activity is no longer visible, either because another activity has taken the foreground or because your activity is being destroyed.
The last chance for your activity to do any processing before it is destroyed. Normally you’d get to this point because the activity is done and the framework called its
finish method. But as mentioned earlier, the method might be called because Android has decided it needs the resources your activity is consuming.
It is important to take advantage of these methods to provide the best user experience possible.
Android Service Lifecycle
The lifecycle for a service is similar to that for an activity, but different in a few important details:
onResume(), onPause(), and
onStop()are not needed:
Services can be started when a client calls the
Context.startService(Intent) method. If the service isn’t already running, Android starts it and calls its
onCreate() method followed by the
onStart() method. If the service is already running, its
onStart() method is invoked again with the new intent. So it’s quite possible and normal for a service’s
onStart() method to be called repeatedly in a single run of the service.
We know that a service generally has no user interface, so there isn’t any need for the onPause, onResume or onStop methods. Whenever a service is running, it is always in the background.
If a client needs a persistent connection to a service, it can call the
Context.bindService method. This creates the service if it is not running, and calls
onCreate() but not
onStart. Instead, the
onBind method is called with the client’s intent, and it returns an
IBind object that the client can use to make further calls to the service. It’s quite normal for a service to have clients starting it and clients bound to it at the same time.
As with an activity, the
onDestroy method is called when the service is about to be terminated. Android will terminate a service when there are no more clients starting or bound to it. As with activities, Android may also terminate a service when memory is getting low. If that happens, Android will attempt to restart the service when the memory pressure passes, so if your service needs to store persistent information for that restart, it’s best to do so in the