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:

  1. Active: the activity was started by the user, is running, and is in the foreground. This is what you are used to thinking of in terms of your activity’s operation.
  2. Paused: the activity was started by the user, is running, and is visible, but another activity is overlaying part of the screen. During this time, the user can see parts of your activity but may not be able to interact with it.
  3. Stopped: the activity was started by the user, is running, but it is completely hidden by other activities that have been launched or switched to.
  4. Destroyed: the activity was destroyed, perhaps due to the user pressing the BACK button.

Android will call so-called “lifecycle methods” on your activity as the activity transitions between these four states.

The Activity developer documentation usually provides some variation of this diagram:

Activity Lifecycle Diagram
Activity Lifecycle Diagram

(the above image is reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License)

This diagram shows the various lifecycle methods and the trigger events that cause them.

The following sections outline these lifecycle methods and their roles. We will see them in use starting in the next chapter.

onCreate() and onDestroy()

We have been implementing onCreate() in all of our Activity subclasses in all the examples. This will get called in two primary situations:

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.

On the other end of the lifecycle, onDestroy() may be called when the activity is shutting down, such as because the activity called finish() (which “finishes” the activity) or the user presses the BACK button. Hence, onDestroy() is mostly for cleanly releasing resources you obtained in onCreate() (if any), plus making sure that anything 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:

Hence, onDestroy() is very likely to be called, but it is not guaranteed.

Also, bear in mind that it may take a long time for onDestroy() to be called. It is called quickly if the user presses BACK to finish the foreground activity. If, however, the user presses HOME to bring up the home screen, your activity is not immediately destroyed. onDestroy() will not be called until Android does decide to gracefully terminate your process, and that could be seconds, minutes, or hours later.

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 anything 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() (for onStart()) or onDestroy() (for onCreate()).

onPause() and onResume()

The onResume() method is called just before your activity comes to the foreground, either after being initially launched, being restarted from a stopped state, or 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:

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 in onResume().

Once onPause() is called, Android reserves the right to kill off your activity’s process at any point. Hence, you should not be relying upon receiving any further events.

Stick to the Pairs

If you initialize something in onCreate(), clean it up in onDestroy().

If you initialize something in onStart(), clean it up in onStop().

If you initialize something in onResume(), clean it up in onPause().

In other words, stick to the pairs. For example, do not initialize something in onStart() and try to clean it up in onPause(), as there are scenarios where onPause() may be called multiple times in succession (i.e., user brings up a non-full-screen activity, which triggers onPause() but not onStop(), and hence not onStart()).

Which pairs of lifecycle methods you choose is up to you, depending upon your needs. You may decide that you need two pairs (e.g., onCreate()/onDestroy() and onStart()/onStop()). Just do not mix and match between them.

Making the Superclass Happy

If you override a lifecycle method, you need to chain 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 chain to the superclass.

In practice, when you chain to the superclass’ implementation is up to you, so long as it is in the same method (e.g., chaining to super.onCreate() from onCreate()). In theory, though, if you are relying on things that you inherit from Activity, it is safest to:


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.