Android Activity Lifecycle

Filed Under: Android

Activity is one of the primary components in Android Development. No wonder knowing the nooks and corners of Activity is essential as an Android Developer. In this tutorial, we’ll be looking at the lifecycle of an Activity, the various functions invoked in the different stages of an Activity’s runtime.

Overview

An Activity is a single focused thing that the user can see. Let’s see how the lifecycle of an Activity looks like. Which functions are triggered when and why!

android-activity-lifecycle

  • onCreate(): This function is called when the activity is initialized.
    In our Kotlin Activity class, the following function defines onCreate():
    fun onCreate(savedInstanceState: Bundle?)
    We’ll look at what the bundle value contains in a later section.
  • onStart(): This function is called when the activity comes into the foreground but isn’t interactive yet.
  • onResume(): This function is called when the activity is interactive with the user.
  • onPause(): This function is called when the user interaction with the activity isn’t possible.
    Common scenarios: An incoming call comes up. Another application pops up. With the introduction of Android N and the multi-window feature, multiple apps are visible on the screen at one time. Apps that are not in focus would have the onPause() method triggered.
  • onStop(): This function gets triggered when the activity is no longer visible.
  • onDestroy(): This function gets triggered when the activity is destroyed.
    Common scenarios: A new activity starts and the current activity is killed. Pressing back button to exit the application.
  • onRestart() : This function gets triggered whenever the activity starts after being stopped. It differs from onStart() in the fact that it won’t be called when the activity launches for the first time. In the later stages, it’ll always be called before onStart().

Saving and Restoring Activity States

Android provides us with a pair of functions : onSaveInstanceState() and onRestoreInstanceState().
Following are the major scenarios when your activity’s state is saved:

  • When onStop() is triggered.
  • On configuration changes such as screen rotations, changes in screen sizes. Android N has multi-window features, so user often changes the window size of the applications.

Configuration changes generally trigger the application to recreate the current activity by destroying the current view to draw it again. Doing so, we need to save the current state of the activity in the onSaveInstanceState() function as shown below.


override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
    }

The Bundle object stores the field values from the activity in the form of key/value pairs.
The Bundle object is of the type nullable to prevent NPE, thanks to Kotlin.


override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        super.onRestoreInstanceState(savedInstanceState)
    }

onRestoreInstanceState() is only called when a saved state exists.

Note: Android automatically takes care of saving and restoring Views that have a unique ID.

Hence in the below layout, only the value of TextView would be saved and restored.


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="net.androidly.helloworldkotlin.MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CLICK ME"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</android.support.constraint.ConstraintLayout>

To disable saving the view’s state, set the attribute android:saveEnabled to false
For Custom Views we need to explicitly set setSavedEnabled(true) on the widget.

Following code snippet demonstrates saving and restoring state in an activity.


import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {


    var title = "This title variable would reset when the configuration is changed. Let's preserve it"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        textView.setText(title)
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        outState?.putString("title",title)
        super.onSaveInstanceState(outState)
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        textView.setText(savedInstanceState?.getString("title"))
        super.onRestoreInstanceState(savedInstanceState)
    }
}

onRestoreInstanceState() is called only when recreating activity after it was killed by the OS.

Note: Alternatively, the saved instance values can be retrieved in the onCreate function too. But we’ll have to keep a null checker since the bundle object would be null when the activity is created for the first time.


override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (savedInstanceState != null) {
            textView.setText(savedInstanceState.getString("title"))
        } else
            textView.setText(title)
    }

Handling Configuration Changes Ourselves

To prevent recreating the activity on a configuration change, we can set the android:configChanges attribute in the AndroidManifest.xml file as shown below.


<activity android:name=".MainActivity"
          android:configChanges="orientation|keyboardHidden|screenSize"
          android:label="@string/app_name">

Whenever any of the above configuration change happens the following method gets triggered.


override fun onConfigurationChanged(newConfig: Configuration?) {
        super.onConfigurationChanged(newConfig)
    }

This brings an end to this tutorial on Activity Lifecycle.
References: Google Docs

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages