[12] Android Activity Lifecycles - mariamaged/Java-Android-Kotlin GitHub Wiki
Android - Activity Lifecycles
- The user taps a launcher icon to start our activity.
- Then, the user rotates the screen, causing a configuration change.
- Later, the user presses BACK to return to the launcher.
While those things were going on, Android was calling lifecycle methods on our activity, to let us know what is going on.
- An activity, generally speaking, is in one of four states at any point in time:
- Active: the activity was
started by the user
, isrunning
, and isin the foreground
. This is what you are used to thinking of in terms of your activity's operation. - Paused: the activity was
started by the user
,is running
, andis visible
, but another activity isoverlaying part of the screen
. During this time, the user can see parts of your activity but may not be able to interact with it. - Stopped: the activity was
started by the user
,is running
, butis completely hidden
by other activities that have been launched or switched to. - Destroyed: the activity was destroyed, perhaps due to the user pressing the BACK button.
- Active: the activity was
1. onCreate() and onDestroy()
- onCreate() will be called in two primary situations:
- When the activity is
launched by the user
, such as from alauncher icon
, onCreate() will be created with anull parameter
. - If the activity
undergoes a configuration change
, by default your activity will bere-created
and onCreate() will be called.
- When the activity is
In general, onCreate() is where you initialize your user interface and set up anything that needs to be done once, regardless of how the activity gets used.
- onDestroy() may be called on the end of the lifecycle when the activity is shutting down.
- The activity called finish().
- The user presses the BACK button.
- Hence, onDestroy() is mostly for:
Cleaning resources
you obtained in onCreate() (if any).- Plus making sure that anything that you started up outside of lifecycle methods gets stopped, such as background threads.
Bear in mind, though, that onDestroy() may not be called. This would occur in a few circumstances:
- You crash with an
unhandled exception
. - The user
force-stops
your application, such as through the Settings app. - Android has an urgent need to free up the RAM (e.g., to handle an incoming phone call), wants to terminate your process, and cannot take the time to call all the lifecycle methods.
- If the user presses HOME to being up the home screen, your activity is not automatically destroyed.
- onDestroy() will not be called until Android does decide to gracefully terminate your app, and that could be seconds, minutes, or hours later.
2. onStart(), onRestart(), and onStop()
- An activity can
come to the foreground
either because:- It is first being launched, or because it is being brought back to the foreground after having been hidden (e.g., by another app's activity).
- The onStart() method is called in either of those cases.
- The onRestart() method is called in the case where the activity had been stopped and is now restarting.
- Conversely, onStop() is called when the activity is about to be stopped.
- Primarily, in onStop(), you clean up everything you set up in onStart().
- Once started, your activity is visible, at least partially.
- Anything that should be happening while your activity is visible should be set up in onCreate() or onStart() and cleaned up in onStop().
3. onPause() and onResume()
- The
onResume()
method is called just before your activity comes to foreground, either:- After being initially launched.
- Before restarted from a stopped state.
- After a pop-up dialog (e.g., incoming call) is cleared.
- When your activity is resumed and is now fully in the foreground, the user can interact with it:
- They can interact with widgets.
- Navigation button clicks, such as BACK, affect your activity.
- Hardware inputs, such as from a keyboard, is sent to your activity.
- Conversely, anything that takes over user input-the activation of another activity- will result in your onPause() being called.
- Here, you should undo anything you did on
onResume()
.
- Here, you should undo anything you did on
Once onPause() is called, Android reserves the right to kill of your activity's process at any point. Hence,
you should not be relying upon receiving any further events
.
4. Making the Superclass Happy
If you override a lifeycle method, you need to chin to the superclass' implementation of the method.
- Otherwise, you will crash at runtime with a SuperNotCalledException.
Android Studio
will warn you
if you implement a lifecycle method and fail to chin to the superclass.
- It is safest:
- Chain to the superclass
before
doing your own work for the creation methods (onCreate(), onStart(), onResume()). - Chain to the superclass
after
doing your own work for the destruction set of methods (onPause(), onStop(), onDestroy()).
- Chain to the superclass
5. Context Anti-Pattern: Outliving It
private lateinit var doNotDoThis: View
class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
doNotDoThis = showElapsed // from the SimpleBloom, showElapsed is a widget.
}
}
- We take a widget from our activity's layout and we assign it to a global property.
- On this surface, this may not seem all that bad.
- However, when the activity is destroyed - due to a configuration change, BACK button press, etc. - we now have a memory leak.
Each widget holds a
reference
to the activity that created it.
- In this case, doNotDoThis has a reference back to our MainActivity.
- Since doNotDoThis is
global in scope
, that widget cannot begarbage collected
. - And since the doNotDoThis reference prevents the widget from being
garbage collected
, it prevents the destroyed activity from beinggarbage collected
.
In general, be very careful about having objects that are tied to some Context
outlive
a Context itself.This can include forking a background thread that has a reference to a Context, as that Context cannot be garbage-collected until the thread terminates.