Android Core

Android Activity Life Cycle – The Complete Guide

Android activity life cycle if one of the most asked questions in Android Developer interviews. It is also the one to mess up easily.

You must have already seen this activity lifecycle diagram from developer.android.com and many android development books.

source: developer.android.com

But this is not enough. This diagram just outlines the activity lifecycle callback sequence through it being created to being destroyed. But it doesn’t show how it behaves with more than one activity.

In this post, we’ll take an in-depth look at the android activity life cycle by actually creating an application and using Log Statements. We’ll put log statements all over the app in life cycle methods to check their behaviour.

These are the activity life cycle callbacks we’ll be taking a look at: 

  1. onCreate
  2. onStart
  3. onResume
  4. onSaveInstanceState
  5. onPause
  6. onStop
  7. onDestroy
  8. onRestoreInstanceState

The Setup

We’ll be having two activities: 1. ActivityA(MainActivity)  2. ActivityB and we’ll be exploring the following situations in the activity life cycle.

  1. Starting ActivityA (on app launch)
  2. Starting ActivityB over ActivityA
  3. Pressing back (returning) from ActivityB to ActivityA
  4. Pressing back (exiting app) from ActivityA
  5. Rotating phone in ActivityA (changing orientation)
  6. Pressing home button

First create an Android Studio project. In the MainActivity.kt file, add the following methods:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class MainActivity : AppCompatActivity() {
    var TAG = "AndroidVille"
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "Activity A"
        Log.d(TAG, "Activity A: onCreate")
    }
 
    override fun onStart() {
        super.onStart()
        Log.d(TAG, "Activity A: onStart() ")
    }
 
    override fun onResume() {
        super.onResume()
        Log.d(TAG, "Activity A: onResume() ")
    }
 
    override fun onPause() {
        super.onPause()
        Log.d(TAG, "Activity A: onPause() ")
    }
 
    override fun onSaveInstanceState(outState: Bundle) {
        outState.putString("androidville", "Hello there")
        super.onSaveInstanceState(outState)
        Log.d(TAG, "Activity A: onSaveInstanceState() ")
    }
 
    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        super.onRestoreInstanceState(savedInstanceState)
        Log.d(TAG, "Activity A: onRestoreInstanceState() ")
    }
 
    override fun onRestart() {
        super.onRestart()
        Log.d(TAG, "Activity A: onRestart() ")
    }
 
    override fun onStop() {
        super.onStop()
        Log.d(TAG, "Activity A: onStop() ")
    }
 
    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "Activity A: onDestroy() ")
    }
 
    fun launchNewActivity(v: View) {
        startActivity(Intent(this, ActivityB::class.java))
    }

Now create another activity (ActivityB), and add the same methods, but this time, replace the “ActivityA” text with “ActivityB” in all the log statements.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.example.androidactivitylifecycle
 
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
 
class ActivityB : AppCompatActivity() {
    var TAG = "AndroidVille"
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_b)
        title = "Activity B"
        Log.d(TAG, "Activity B: onCreate")
    }
 
 
    override fun onStart() {
        super.onStart()
        Log.d(TAG, "Activity B: onStart() ")
    }
 
    override fun onResume() {
        super.onResume()
        Log.d(TAG, "Activity B: onResume() ")
    }
 
    override fun onPause() {
        super.onPause()
        Log.d(TAG, "Activity B: onPause() ")
    }
 
    override fun onSaveInstanceState(outState: Bundle) {
        outState.putString("androidville", "Hello there")
        super.onSaveInstanceState(outState)
        Log.d(TAG, "Activity B: onSaveInstanceState() ")
    }
 
    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
        super.onRestoreInstanceState(savedInstanceState)
        Log.d(TAG, "Activity B: onRestoreInstanceState() ")
    }
 
    override fun onRestart() {
        super.onRestart()
        Log.d(TAG, "Activity B: onRestart() ")
    }
 
    override fun onStop() {
        super.onStop()
        Log.d(TAG, "Activity B: onStop() ")
    }
 
    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "Activity B: onDestroy() ")
    }
 
}

Now, we’ll create a Log Filter to just focus on our custom log statements. For this, 

  1. Click on the “Logcat” tab on the bottom of the Android Studio. 
  2. Then click on the dropdown menu next to where it says “Regex”. Then select “Edit Filter Configuration”
  3. In the popup window, enter the name of the Filter (whatever you like). Enter the TAG of your log statement in “Log Tag”. It should be the same as the TAG variable inside the activities. Then click on “Ok”.

This will help you filter out the unnecessary log statements and focus on the activity life cycle ones.

Activity Life Cycle (on app launch)

With this setup, we’re ready to explore the activity life cycle method’s call sequence. Go ahead and run the app, make sure your logcat window is opened up and clean. 

When the app launches, this is the callback sequence:

  1. onCreate
  2. onStart
  3. onResume

First, the ActivityA’s onCreate method is called, which sets up the layout of the activity. Then we have onStart which is the place to set up things such as broadcast receivers. And finally onResume when Activity is interactive.

Launching ActivityB over ActivityA *Important*

This is the most commonly asked question about android activity life cycle. What are the callback methods when one activity is launched above another. 

I cannot stress enough the importance of this question and also one that people can get wrong. Because it’s so simple, I used to commit this mistake of saying all methods of ActivityA and then B.

Let’s see what happens here:

This is the activity life cycle callback sequence: 

  1. onPause – ActivityA
  2. onCreate – ActivityB
  3. onStart – ActivityB
  4. onResume – ActivityB
  5. onStop – ActivityA
  6. onSaveInstanceState – ActivityA

First, the ActivityA is paused, then life cycle methods of ActivityB are called. But finally the ActivityA is stopped.

Important point to note here is that ActivityA is stopped (not destroyed) after ActivityB has been created and is interactive.

Pressing Back Button from ActivityB 

Now when pressing back from ActivityB we land on ActivityA and this is the callback sequence:

  1. onPause – ActivityB
  2. onRestart – ActivityA
  3. onStart – ActivityA
  4. onResume – ActivityA
  5. onStop – ActivityB
  6. onDestroy – ActivityB

Here we see that at the end, ActivityB is destroyed. Notice that when launching B on A, ActivityA wasn’t destroyed but stopped, and it’s process lived on.

Pressing Back Button from ActivityA

Let’s see what happens when we press the back button from ActivityA (MainActivity).

  1. onPause – ActivityA
  2. onStop – ActivityA
  3. onDestroy – ActivityA

Since ActivityA is the last activity, on pressing back button, the app exits and the process of ActivityA is destroyed.

Rotating the device (activity life cycle in orientation change) *Important*

This is another important scenario in these questions. And this one is a bit unique, which makes use of onRestoreInstanceState. We’ll be rotating the device from ActivityA.

Here are the callback method call sequence:

  1. onPause – ActivityA
  2. onStop – ActivityA
  3. onSaveInstanceState – ActivityA
  4. onDestroy – ActivityA
  5. onCreate – ActivityA
  6. onStart – ActivityA
  7. onRestoreInstanceState – ActivityA
  8. onResume – ActivityA

You can get the key value pairs you store from onSaveInstanceState, inside onRestoreInstanceState.

Pressing home button from ActivityA

On pressing home button from ActivityA, you’ll get the following callback sequence:

  1. onPause – ActivityA
  2. onStop – ActivityA
  3. onSaveInstanceState – ActivityA

And when you come back from paused state (by pressing recents button on android), following is the sequence:

  1. onRestart – ActivityA
  2. onStart – ActivityA
  3. onResume – ActivityA

So these were some of the scenarios in Android Activity Life Cycle. Let me know if you want me to post some other scenarios as well. In the upcoming posts, I’ll try to make one with fragments lifecycle and how they work with activity life cycle.

Published on Java Code Geeks with permission by Ayusch Jain, partner at our JCG program. See the original article here: Android Activity Life Cycle – The Complete Guide

Opinions expressed by Java Code Geeks contributors are their own.

Ayusch Jain

Ayusch is a Software Engineer currently working in Android Development. He's worked long enough that he's transformed into an Android himself :P. Additionally, he also maintains a community of Android developers called: AndroidVille and writes about Android on his website: https://ayusch.com
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
mehmet
mehmet
2 years ago

That is very good explaination.
Thank you.

Back to top button