This image has nothing to do with the article, but Medium recommended to add a picture ¯\_(ツ)_/¯

In-depth analysis of Activity’s Lifecycle

Abhilash Das
AndroidPub
Published in
6 min readSep 26, 2019

--

Let me ask you a few questions.

1. Which Lifecycle method will get called when a dialog appears in an activiy?
2. When you start another activity from one activity, what lifecycle methods get called, and in what sequence?

Try to answer all the above questions in your head.

.

.

.

.

Done? Let’s check your answer.

Let’s test out the first question. You can find the sample Github project at the end of this article.

class Main7Activity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main7)
Log.d("lifecycle-test", "Main7Activity - onCreate")

btn.setOnClickListener {
Log.d("lifecycle-test", "show dialog button clicked")
AlertDialog.Builder(this)
.setTitle("This is a dialog")
.setMessage("This is a dialog")
.setPositiveButton(
android.R.string.yes
) { _, _ ->
}
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
}

override fun onPause() {
Log.d("lifecycle-test", "Main7Activity - onPause")
super.onPause()
}

override fun onResume() {
Log.d("lifecycle-test", "Main7Activity - onResume")
super.onResume()
}

override fun onDestroy() {
Log.d("lifecycle-test", "Main7Activity - onDestroy")
super.onDestroy()
}

override fun onStart() {
Log.d("lifecycle-test", "Main7Activity - onStart")
super.onStart()
}

override fun onStop() {
Log.d("lifecycle-test", "Main7Activity - onStop")
super.onStop()
}
}

When you click on the button, an alert dialog will be shown but

Log.d("lifecycle-test", "Main7Activity - onPause")

will never get logged. What we generally think that when a dialog is shown over an activity, onPause() method will get called. But that’s not the case. In the official android doc, it’s mentioned that

A new, semi-transparent activity (such as a dialog) opens. As long as the activity is still partially visible but not in focus, it remains paused.

The onPause() is called when your activity is no longer at the top of the activity stack. A Dialog by itself is not an Activity, so will not replace the current Activity at the top of the stack, so will not cause anything to pause. Displaying the dialog-as-an-Activity will cause the new Activity to be on the top of the stack, pausing what previously was there.

There are two more such scenarios when onPause() will get called.

Some event interrupts app execution such as receiving a phone call, the user’s navigating to another activity, or the device screen’s turning off.

In Android 7.0 (API level 24) or higher, multiple apps run in multi-window mode. Because only one of the apps (windows) has focus at any time, the system pauses all of the other apps.

Then what about onStop() ?

Let’s do one more experiment. Let’s start Main3Activity from Main2Activity on button click and observe lifecycle changes.

class Main2Activity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
Log.d("lifecycle-test","Main2Activity - onCreate")
btn.setOnClickListener {
startActivity(Intent(this, Main3Activity::class.java))
}
}

override fun onPause() {
Log.d("lifecycle-test","Main2Activity - onPause")
super.onPause()
}

override fun onDestroy() {
Log.d("lifecycle-test","Main2Activity - onDestroy")
super.onDestroy()
}

override fun onStart() {
Log.d("lifecycle-test","Main2Activity - onStart")
super.onStart()
}

override fun onStop() {
Log.d("lifecycle-test","Main2Activity - onStop")
super.onStop()
}

override fun onResume() {
Log.d("lifecycle-test", "Main2Activity - onResume")
super.onResume()
}
}

and

class Main3Activity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main3)
Log.d("lifecycle-test","Main3Activity - onCreate")
}

override fun onPause() {
Log.d("lifecycle-test","Main3Activity - onPause")
super.onPause()
}

override fun onDestroy() {
Log.d("lifecycle-test","Main3Activity - onDestroy")
super.onDestroy()
}

override fun onStart() {
Log.d("lifecycle-test","Main3Activity - onStart")
super.onStart()
}

override fun onStop() {
Log.d("lifecycle-test","Main3Activity - onStop")
super.onStop()
}

override fun onResume() {
Log.d("lifecycle-test", "Main3Activity - onResume")
super.onResume()
}
}

When you check the log, you’ll get the below result.

com.example.lifecycle D/lifecycle-test: Main2Activity - onPause
com.example.lifecycle D/lifecycle-test: Main3Activity - onCreate
com.example.lifecycle D/lifecycle-test: Main3Activity - onStart
com.example.lifecycle D/lifecycle-test: Main3Activity - onResume
com.example.lifecycle D/lifecycle-test: Main2Activity - onStop

in flow-diagram, it’ll look something like this:

start Main3Activity from Main2Activity

When you back press from Main3Activity, the following will be the log:

com.example.lifecycle D/lifecycle-test: Main3Activity - onPause
com.example.lifecycle D/lifecycle-test: Main2Activity - onStart
com.example.lifecycle D/lifecycle-test: Main2Activity - onResume
com.example.lifecycle D/lifecycle-test: Main3Activity - onStop
com.example.lifecycle D/lifecycle-test: Main3Activity - onDestroy

again below will be diagram depctin of above flow:

press back from Main3Activity to go to Main2Activity

Let’s analyze what just happened. If I show the above flow in a flow diagram, it

when you start an activity, onPause() method of calling activity will be called. Then onCreate() , onStart() and onResume() method will be called in sequence and then onStop() method of calling activity will be called. That means, the calling activity is in a transient state between its onPause() and onStop() . Until and unless called activity is not fully visible to the user, onStop() method of calling activity won’t get called.

The same process happens when you press the back button. At first, onPause() of child activity is called, Then, until the parent activity is not fully visible, i.e. onStart() and onResume() of parent are not called, onStop() of closing activity won’t get called. After that onStop() and onDestroy() method of child activity will be called.

One more thing, onCreate() of called activity won’t get called until calling activity’s onPause() returns. So don’t do any lengthy operations here.

Everything I explained above can be found in the source code of Activity .

for onPause():

/**
* Called as part of the activity lifecycle when an activity is going into
* the background, but has not (yet) been killed. The counterpart to
* {
@link #onResume}.
*
* <p>When activity B is launched in front of activity A, this callback will
* be invoked on A. B will not be created until A's {
@link #onPause} returns,
* so be sure to not do anything lengthy here.
*
* <p>This callback is mostly used for saving any persistent state the
* activity is editing, to present a "edit in place" model to the user and
* making sure nothing is lost if there are not enough resources to start
* the new activity without first killing this one. This is also a
* good place to do things like stop animations and other things * * that consume a
* noticeable amount of CPU in order to make the switch to the next activity
* as fast as possible, or to close resources that are exclusive access
* such as the camera.
*
* <p>In situations where the system needs more memory it may kill paused
* processes to reclaim resources. Because of this, you should be sure
* that all of your state is saved by the time you return from
* this function. In general {
@link #onSaveInstanceState} is used to save
* per-instance state in the activity and this method is used to store
* global persistent data (in content providers, files, etc.)
*
* <p>After receiving this call you will usually receive a following call
* to {
@link #onStop} (after the next activity has been resumed and
* displayed), however in some cases there will be a direct call back to
* {
@link #onResume} without going through the stopped state.
*
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
*
*
@see #onResume
*
@see #onSaveInstanceState
*
@see #onStop
*/

onStop():

/**
* Called when you are no longer visible to the user. You will next
* receive either {
@link #onRestart}, {@link #onDestroy}, or nothing,
* depending on later user activity.
*
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
*
*
@see #onRestart
*
@see #onResume
*
@see #onSaveInstanceState
*
@see #onDestroy
*/

You can find the source code below:

Try this and answer it on your own. Main6Activity from Main5Activity's onCreate() and Main5Activity from Main4Activity's onCreate() . What will be the sequence of lifecycle methods?

--

--