Android9/27/2020

How to Save Activity State in Android Using onSaveInstanceState

Android applications can restart automatically during runtime configuration changes such as:

  • Screen rotation
  • Language changes
  • Dark mode changes
  • Multi-window mode

When this happens, the Activity is destroyed and recreated.

If developers do not save the UI state properly, variables and temporary data may be lost.

In this tutorial, we will learn how to save and restore Activity state in Android using onSaveInstanceState().


What Is onSaveInstanceState?

onSaveInstanceState() is an Android lifecycle callback used to save temporary UI data before an Activity gets destroyed.

Android automatically restores some UI elements such as:

  • EditText text
  • RecyclerView scroll position
  • Fragment states

However, custom variables must be saved manually.


Why Saving State Is Important

Without proper state handling:

  • Counters reset
  • User progress is lost
  • UI becomes inconsistent
  • User experience suffers

Saving Activity state improves application reliability and usability.


What We Will Build

In this example:

  • User can increment and decrement a counter
  • Counter value survives screen rotation
  • State restores automatically after Activity recreation

Step 1 — Create Layout File

Create the UI inside activity_main.xml.


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="horizontal">

    <Button
        android:id="@+id/button_decrement"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="-" />

    <TextView
        android:id="@+id/text_view_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="0"
        android:textColor="@android:color/black"
        android:textSize="50sp" />

    <Button
        android:id="@+id/button_increment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="+" />

</LinearLayout>

Step 2 — Implement MainActivity.java

Open MainActivity.java and add the following code:


package com.example.savedstateexample;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView textViewCount;

    private int count;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        textViewCount =
                findViewById(R.id.text_view_count);

        Button buttonDecrement =
                findViewById(R.id.button_decrement);

        Button buttonIncrement =
                findViewById(R.id.button_increment);

        buttonDecrement.setOnClickListener(
                new View.OnClickListener() {

                    @Override
                    public void onClick(View view) {
                        decrement();
                    }
                });

        buttonIncrement.setOnClickListener(
                new View.OnClickListener() {

                    @Override
                    public void onClick(View view) {
                        increment();
                    }
                });

        if (savedInstanceState != null) {

            count = savedInstanceState.getInt("count");

            textViewCount.setText(
                    String.valueOf(count)
            );
        }
    }

    private void increment() {

        count++;

        textViewCount.setText(
                String.valueOf(count)
        );
    }

    private void decrement() {

        count--;

        textViewCount.setText(
                String.valueOf(count)
        );
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {

        super.onSaveInstanceState(outState);

        outState.putInt("count", count);
    }
}

How This Implementation Works

The workflow is:

  1. User changes counter value
  2. Android destroys Activity during rotation
  3. onSaveInstanceState() stores counter value
  4. Activity recreates automatically
  5. Saved value restores inside onCreate()

How Android Lifecycle Handles State

When configuration changes happen:


onPause()
↓
onStop()
↓
onSaveInstanceState()
↓
onDestroy()
↓
onCreate()
↓
onStart()
↓
onResume()

This lifecycle allows Android to preserve temporary UI data.


What Type of Data Should Be Saved?

Good examples:

  • Counter values
  • Temporary form data
  • Selected tabs
  • Scroll positions
  • Search queries

What Should NOT Be Saved?

Avoid storing:

  • Large images
  • Database objects
  • Huge collections
  • Heavy serialized objects

Large Bundle data can cause performance issues.


Common Mistakes Developers Make

1. Forgetting Null Checks

Always check:


if (savedInstanceState != null)

before restoring values.


2. Saving Large Data

Bundles are intended for lightweight UI state only.


3. Not Updating UI After Restore

Restoring variables without updating UI components causes incorrect screen states.


Modern Android Recommendations

Modern Android applications often use:

  • ViewModel
  • SavedStateHandle
  • Jetpack Compose state management
  • MVVM architecture

These approaches improve lifecycle-aware state management.


ViewModel vs onSaveInstanceState

ViewModel onSaveInstanceState
Survives configuration changes Stores temporary UI state
Better for business logic Better for small UI data
Lifecycle aware Bundle based

FAQ

Why does Android recreate Activities during rotation?

Android recreates Activities to reload resources for the new configuration.

Can onSaveInstanceState save large objects?

No. It should only store lightweight temporary UI data.

What is the modern alternative to this approach?

ViewModel and SavedStateHandle are modern lifecycle-aware solutions.


Conclusion

Handling Activity state correctly is an important part of Android development.

Using onSaveInstanceState() helps preserve temporary UI data during configuration changes and improves user experience.

Modern Android applications should combine lifecycle-aware architecture with proper state management techniques.


About the Author

Salil Jha is a Full Stack and Mobile Developer with experience in Android, React Native, fintech applications, scalable SaaS systems, and developer tooling platforms.

CodeChain Dev — Build Modern Products. Solve Real Problems.

Deep Structural Diagnostics.

Mastering JSON is only the first step. Use our industrial-grade workbench to format, validate, and synthesize models for your production APIs.