Skip to content
beginner Phase 2 · Android Fundamentals

Activity Lifecycle

Master the Activity lifecycle callbacks: onCreate, onStart, onResume, onPause, onStop, onDestroy.

50m
3 problems
Topic Progress 0%

Activity Lifecycle Overview

The Activity Lifecycle

An Activity represents a single screen in your app. Android manages activities through a lifecycle — a series of states and callbacks that fire as the activity moves through creation, foreground, background, and destruction.

Lifecycle States

                    ┌──────────────┐
                    │  Created     │
                    └──────┬───────┘
                           │
                    ┌──────▼───────┐
          ┌────────►│  Started      │◄────────┐
          │         └──────┬───────┘         │
          │                │                  │
  Restart │         ┌──────▼───────┐  Resume  │
          │         │  Resumed      │─────────┘
          │         └──────┬───────┘
          │                │
          │         ┌──────▼───────┐
          └─────────┤  Paused       │
                    └──────┬───────┘
                           │
                    ┌──────▼───────┐
                    │  Stopped      │
                    └──────┬───────┘
                           │
                    ┌──────▼───────┐
                    │  Destroyed    │
                    └──────────────┘

Lifecycle Callbacks

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Activity is being created — initialize UI, restore saved state
    }

    override fun onStart() {
        super.onStart()
        // Activity becomes visible — register receivers, bind services
    }

    override fun onResume() {
        super.onResume()
        // Activity is in foreground — start animations, acquire wake lock
    }

    override fun onPause() {
        super.onPause()
        // Activity partially obscured — save unsaved data, release resources
    }

    override fun onStop() {
        super.onStop()
        // Activity not visible — release expensive resources
    }

    override fun onDestroy() {
        super.onDestroy()
        // Activity being destroyed — clean up all references
    }

    override fun onRestart() {
        super.onRestart()
        // Called after onStop but before onStart — not a direct callback from lifecycle
    }
}

What Triggers Each Callback

Callback Trigger
onCreate First time the activity is created (or recreated after destruction)
onStart Activity transitioning to visible state
onResume Activity coming to foreground
onPause Another activity coming to foreground (partial obstruction)
onStop Activity no longer visible (another activity fully covers it)
onDestroy Activity being removed from memory

The Flow in Practice

When you press Home: onPauseonStop. The activity is still in memory but not visible. When you return: onRestartonStartonResume.

When you rotate the device: onPauseonSaveInstanceStateonStoponDestroyonCreateonStartonRestoreInstanceStateonResume. The activity is recreated because rotation is a configuration change.

When a dialog-style activity appears on top: only onPause fires — the underlying activity is still partially visible.

Saving and Restoring State

Saving and Restoring State

Activities can be destroyed and recreated at any time — configuration changes (rotation, language, dark mode), low memory conditions, or process death. You must save transient UI state to survive these events.

onSaveInstanceState

class MainActivity : AppCompatActivity() {
    private var counter = 0

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt("counter", counter)
        // Only save transient state — not large objects
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        counter = savedInstanceState?.getInt("counter", 0) ?: 0
    }
}

Key rules:

  • Save in onPause or onSaveInstanceState (before API 28, onSaveInstanceState was after onStop; now it's before)
  • Only save lightweight data — Bundle is serialized and passed across processes
  • Don't save Views, Contexts, or large objects — these cause TransactionTooLargeException

ViewModel: Surviving Configuration Changes

ViewModel survives configuration changes. Use it for data that should persist across activity recreation:

class CounterViewModel : ViewModel() {
    private val _count = MutableLiveData(0)
    val count: LiveData<Int> = _count

    fun increment() {
        _count.value = (_count.value ?: 0) + 1
    }
}

class MainActivity : AppCompatActivity() {
    private val viewModel: CounterViewModel by viewModels()

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

        viewModel.count.observe(this) { count ->
            findViewById<TextView>(R.id.textView).text = count.toString()
        }

        findViewById<Button>(R.id.button).setOnClickListener {
            viewModel.increment()
        }
    }
}

ViewModel is not destroyed during rotation — it's retained in a ViewModelStore. It IS destroyed when the activity is permanently destroyed (e.g., user presses Back).

When to Use Each

  • onSaveInstanceState: Small UI state (scroll position, form input, checkbox state)
  • ViewModel: Data that survives configuration changes (network results, user data)
  • SavedStateHandle: ViewModel state that also survives process death
class SearchViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    val query = savedStateHandle.getLiveData<String>("query", "")

    fun updateQuery(query: String) {
        savedStateHandle["query"] = query
    }
}

Lifecycle-Aware Components

Lifecycle-Aware Components

Android Jetpack provides LifecycleObserver and LifecycleOwner to handle lifecycle-aware behavior without coupling to specific callbacks.

LifecycleObserver

class LocationTracker(private val context: Context) : DefaultLifecycleObserver {

    private val locationManager = context.getSystemService(LocationManager::class.java)
    private var locationListener: LocationListener? = null

    override fun onStart(owner: LifecycleOwner) {
        // Start tracking when activity is visible
        locationListener = object : LocationListener {
            override fun onLocationChanged(location: Location) {
                Log.d("Location", "${location.latitude}, ${location.longitude}")
            }
        }
        locationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER, 0L, 0f, locationListener!!
        )
    }

    override fun onStop(owner: LifecycleOwner) {
        // Stop tracking when activity is not visible
        locationListener?.let { locationManager.removeUpdates(it) }
        locationListener = null
    }
}
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycle.addObserver(LocationTracker(this))
        // No manual cleanup needed — lifecycle handles it
    }
}

Process Death

Android can kill your process when the app goes to background (no visible activities). On return, the system recreates the activity from scratch but restores the Bundle. The ViewModel is NOT restored after process death — use SavedStateHandle for data that must survive both configuration changes and process death.

Common Lifecycle Pitfalls

  1. Starting an animation in onCreate: It runs before the activity is visible. Use onResume.
  2. Registering a listener in onCreate but not unregistering: Causes memory leaks. Use lifecycle.addObserver or unregister in onStop/onDestroy.
  3. Accessing Views after onDestroy: Causes NPE. Observe lifecycle state in coroutines.
  4. Heavy work in onCreate: Blocks UI. Move to viewModelScope or a background thread.

Quiz

1. What is the correct order of lifecycle callbacks when an activity first launches?

Question 1 options

2. When does onSaveInstanceState get called?

Question 2 options

3. What happens to a ViewModel during a configuration change like screen rotation?

Question 3 options

4. Which callback should you use to register a location listener?

Question 4 options

Flashcards

Question

What is the Activity lifecycle order from creation to destruction?

Answer

onCreate → onStart → onResume → (running) → onPause → onStop → onDestroy

Question

When should you use onSaveInstanceState vs ViewModel?

Answer

onSaveInstanceState for lightweight UI state (scroll position, form input). ViewModel for data that survives configuration changes (network results, user data).

Question

What is a LifecycleObserver?

Answer

A component that automatically responds to lifecycle events, allowing you to start/stop work without manually registering callbacks.

Question

What happens to ViewModel after process death?

Answer

ViewModel is destroyed. Use SavedStateHandle for data that must survive both configuration changes and process death.

Revision Notes

Key Takeaways

  • 1. Activities are recreated on configuration changes — save state to survive
  • 2. onCreate initializes UI; onResume starts foreground work; onPause stops it
  • 3. ViewModel survives configuration changes but not process death
  • 4. SavedStateHandle bridges ViewModel and process death survival
  • 5. LifecycleObserver eliminates manual callback management and prevents leaks

Interview Tips

  • Draw the lifecycle diagram from memory — interviewers love this
  • Explain the difference between onPause and onStop triggers
  • Know when ViewModel is destroyed vs when SavedStateHandle survives
  • Be ready to discuss how rotation recreates the activity

Cheat Sheet

Activity Lifecycle Cheat Sheet

Callbacks (in order):

  1. onCreate — Initialize UI, restore Bundle
  2. onStart — Activity visible
  3. onResume — Activity in foreground
  4. onPause — Partially obscured
  5. onStop — Not visible
  6. onDestroy — Being removed

State Saving:

  • onSaveInstanceState — lightweight UI state
  • ViewModel — survives config changes
  • SavedStateHandle — survives process death

Common Mistakes:

  • Starting animation in onCreate (use onResume)
  • Not unregistering listeners (use lifecycle observer)
  • Saving large objects in Bundle (causes TransactionTooLargeException)