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: onPause → onStop. The activity is still in memory but not visible. When you return: onRestart → onStart → onResume.
When you rotate the device: onPause → onSaveInstanceState → onStop → onDestroy → onCreate → onStart → onRestoreInstanceState → onResume. 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
onPauseoronSaveInstanceState(before API 28,onSaveInstanceStatewas afteronStop; now it's before) - Only save lightweight data —
Bundleis 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
- Starting an animation in
onCreate: It runs before the activity is visible. UseonResume. - Registering a listener in
onCreatebut not unregistering: Causes memory leaks. Uselifecycle.addObserveror unregister inonStop/onDestroy. - Accessing Views after
onDestroy: Causes NPE. Observe lifecycle state in coroutines. - Heavy work in
onCreate: Blocks UI. Move toviewModelScopeor a background thread.
Quiz
1. What is the correct order of lifecycle callbacks when an activity first launches?
2. When does onSaveInstanceState get called?
3. What happens to a ViewModel during a configuration change like screen rotation?
4. Which callback should you use to register a location listener?
Flashcards
Question
What is the Activity lifecycle order from creation to destruction?
Click to reveal answer
Answer
onCreate → onStart → onResume → (running) → onPause → onStop → onDestroy
Question
When should you use onSaveInstanceState vs ViewModel?
Click to reveal answer
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?
Click to reveal answer
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?
Click to reveal answer
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):
onCreate— Initialize UI, restore BundleonStart— Activity visibleonResume— Activity in foregroundonPause— Partially obscuredonStop— Not visibleonDestroy— Being removed
State Saving:
onSaveInstanceState— lightweight UI stateViewModel— survives config changesSavedStateHandle— survives process death
Common Mistakes:
- Starting animation in onCreate (use onResume)
- Not unregistering listeners (use lifecycle observer)
- Saving large objects in Bundle (causes TransactionTooLargeException)