Pile them up: The Activity Stack
You can determine the state of an activity by its position in the stack.
As activities are started, they are pushed on to the top of the stack. The previous activity is stopped and moves down the stack.
Using the back button pops the top activity off the stack and destroys it. The next activity in the stack is moved to the top.
New activities are pushed onto the top of the stack. Pressing the Back button pops the top activity off the stack and destroys it. The next activity in the stack is now on top
Activities are continually being created and destroyed. In this process, they pass through 4 states as they move in and out of the stack.
The Four States
Interacting: The Active State
Activities at the top of the stack are visible, focused and in the foreground. The user is interacting with it and the Android run time will try and keep it alive as a priority.
The Android run time will kill lower down activities if this activity needs extra resources.
Active activities are paused if another activity becomes active.
Out of focus: The Paused State
Paused activities may be visible but do not have focus. An active activity may partially obscure it.
Users are not interacting with it. It’s treated as if it’s active but it receives no user input.
In extreme cases these activities may be killed to free resources for active activities.
If a paused activity is fully obscured, it stops.
Just a memory: The Stopped State
Activities that are no longer visible are stopped.
They remain in memory and retain their state information. The run time will kill it if it needs resources.
This is where you should save data and the current UI and also stop any non-critical operations.
A stopped activity will become inactive if you exit or close it.
In the wilderness: The Inactive State
An activity is inactive after being killed and before being launched.
Inactive activities are removed from the stack and must be restarted before they can be displayed.
The big kahuna: The Android Memory Manager
The Android Memory Manager handles the transitions between these states.
If resources are needed for active activities, the memory manager starts by closing apps with inactive activities, then those with stopped activities. In extreme cases it closes those with paused activities.
Keep it under wraps
Users shouldn’t be aware of the activity’s movement in and out of these states.
Make the transitions seamless by saving all UI states and persist all data when the activity pauses or is stopped. The activity should then restore that state when it becomes active.
Monitoring state changes: The guys that jump when the bell rings
Android has a number of event handlers that fire when an activity moves through its lifetimes:
- onCreate – called when the activity is first created. Set up the activity here. This would include: creating views and binding data to lists. It also receives a saved state bundle which is used to rebuild a previous state if there was one. Always followed by onStart()
- onStart – called when the activity is becoming visible to the user. Followed by onResume() if the activity moves to the foreground else by onStop() if it becomes hidden
- onRestart – called after the activity has stopped, just before it’s to be started again. Always followed by onStart()
- onResume – called when the activity starts interacting with the user. At this point the activity is at the top of the stack. The user is interacting with it. It’s always followed by onPause()
- onPause – always called when the activity is being placed in the background or is about to be destroyed. You should save persistent data here rather than in onSaveInstanceState. Any code here should be lightweight and quick
- onStop – called when the activity is no longer visible. This could be because a new activity started, an existing one has been brought to the front, or this one is about to be destroyed. Followed by onStart if this activity is coming back to interact with the user or onDestroy if it’s going away
- onDestroy –called before the activity is destroyed. This could be because the activity is finishing or the system is destroying the activity to save resources
Nine lives. Well not quite! Understanding activity lifetimes
You need to understand the activity life-cycle to give a seamless user experience and properly manage the resources.
The Activity‘s lifetimes
Within an Activity’s full lifetime, between onCreate and onDestroy, it goes through one or more cycles of the active and visible lifetimes.
Each transition triggers one of the event handlers described above. Use these handlers to ensure that the user is unaware of these transitions.
The following sections take a closer look at each of these lifetimes.
From the cradle to the grave: The Full lifetime
The full lifetime stretches from the onCreate to the onDestroy methods.
You set up the initial global state in onCreate and release all resources in onDestroy.
This is where you initialise the activity, inflate the User Interface, get references to Fragments, allocate references to class variables, attach data to views, and start services.
If the activity is restoring itself, it uses the saved state contained in a bundle created when onSaveInstanceState was called.
You can restore the sate here or in onRestoreInstanceState.
Here’s where we clean up resources created in onCreate and close all network and database connections.
Note that onDestroy may not be called.
On the catwalk: The Visible lifetime
An activity’s visible lifetime starts with onStart and ends with onStop
During this time the activity may not have focus but it is visible to the user.
It is possible that the run time will kill the activity during its visible lifetime without calling onStop.
Use onStop to pause or stop processes, like Services, Threads, and Broadcast receivers, which are used exclusively to update the User interface. There is no point in consuming resources to update a UI that’s not visible.
Use onStart or onResume to resume or restart these processes when the UI is once again visible.
Use onRestart to start special processes that you want running only when the Activity restarts within its full lifetime.
In the gym: The Active Lifetime
The Active lifetime starts with onResume and ends with onPause.
Active activities are in the foreground, interacting with the user.
An activity goes through many active lifetimes before it’s destroyed. The Active lifetime ends when a new activity is displayed, the device goes to sleep or the activity loses focus.
Keep the code in onResume and onPause methods fast and lightweight to ensure a responsive app while the activity moves in and out of the foreground.
The onSaveInstanceState method is called before onPause. This is where you can save the User Interface state. The saved state is then passed on to the onCreate and onRestoreInstanceState methods to rebuild the activity state.
It automatically saves the state of all views with an ID.
onSaveInstanceState and onPause will be called in the active lifetime before the activity is killed.
Note that onSaveInstanceState is sometimes not called. For example, when the activity is about to be destroyed and will not be restored (as when the back button is pressed).
If it is called, then it will be called before onStop(). However, there is no guarantee if it will be called before or after onPause().
onRestoreInstanceState restores the state of any view saved by onSaveInstanceState.
onRestoreInstanceState is called after onStart() and before onPostCreate().
Most of the time you’d restore the state in onCreate but sometimes you may want to do it here after all initialisation has been done in onCreate.
You may also be interested in the article on how to save the Activity's Instance State when the device's orientation is changed.
I hope that you have found this tutorial helpful.