Activity Lifecycle (Deep Dive)
Deep dive into Activity lifecycle states, transitions, configuration changes, and state preservation techniques.
Module 5: Activity Lifecycle (Deep Dive)
Learning Objectives
By the end of this module, you’ll understand:
- Why Activities have a lifecycle
- How Android creates and destroys Activities
- Every lifecycle callback in detail
- The Activity state machine
- Configuration changes
- Process death vs Activity destruction
- Saving and restoring state
- Lifecycle-aware components
- Common bugs and best practices
- Real-world lifecycle scenarios
1. Why Does Android Need a Lifecycle?
Let’s begin with a thought experiment.
Suppose Android worked like a desktop application.
main()
↓
Window Opens
↓
Runs Forever
↓
User Closes
↓
Exit
Would this work on a phone?
No.
Phones have limited:
- RAM
- CPU
- Battery
- Storage
And users constantly switch between apps.
Example:
Instagram
↓
Camera
↓
WhatsApp
↓
Chrome
↓
Maps
↓
Phone Call
↓
Back to Instagram
Should Instagram stay fully active the entire time?
No.
That would:
- waste battery
- consume memory
- reduce performance
- make multitasking impossible
Android therefore manages app lifecycles aggressively.
2. Android Owns Your Activity
One of the biggest misconceptions:
“I create my Activity.”
Actually, Android does.
When you write:
class MainActivity : AppCompatActivity()
you’re defining a blueprint.
The actual creation looks more like:
User taps icon
↓
Android System
↓
Creates MainActivity
↓
Calls lifecycle callbacks
Your Activity exists because Android instantiated it—not because you called a constructor.
3. Think of an Activity as an Actor
Imagine an actor in a theater.
They don’t decide:
- when to enter
- when to leave
- when to pause
The director does.
Android is the director.
Android
↓
Create Activity
↓
Start Activity
↓
Pause Activity
↓
Resume Activity
↓
Destroy Activity
Your Activity simply responds to instructions.
4. The Complete Lifecycle
Here is the full lifecycle:
onCreate()
│
▼
onStart()
│
▼
onResume()
│
Activity Running
│
User Leaves App
│
▼
onPause()
│
▼
onStop()
│
Return to App
│
onRestart()
│
onStart()
│
onResume()
│
Finish Activity
│
onDestroy()
This isn’t just a sequence.
It’s a state machine.
Android moves your Activity between states depending on what the user and system are doing.
5. Activity States
An Activity is always in one of several logical states.
Created
↓
Started
↓
Resumed
↓
Paused
↓
Stopped
↓
Destroyed
Only one Activity is typically in the Resumed state at a time because that’s the one interacting with the user.
6. onCreate()
This is the first callback after Android creates the Activity instance.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
Think of it as:
“Build everything needed for this screen.”
Typical responsibilities:
- Inflate the layout
- Initialize ViewBinding
- Create ViewModel references
- Restore saved state
- Configure RecyclerViews
- Set click listeners
Avoid:
- Long-running work
- Blocking the main thread
- Heavy network calls directly
onCreate() is called once per Activity instance.
If Android destroys the Activity and creates a new one (e.g., rotation), the new instance gets its own onCreate().
7. onStart()
The Activity is now becoming visible.
onCreate()
↓
onStart()
↓
User can SEE it
↓
Not yet interacting
Use this for work tied to visibility.
Examples:
- Register listeners
- Start observing data (when appropriate)
- Prepare UI resources
8. onResume()
This is when the Activity moves to the foreground and the user can interact with it.
Activity
↓
Visible
↓
Interactive
↓
Receiving Touch Events
Good places to:
- Start animations
- Resume camera preview
- Resume sensors
- Resume gameplay
When onResume() finishes, the user is actively using your screen.
9. onPause()
This callback happens when the Activity is losing focus, but it may still be partially visible.
Example:
User opens dialog
↓
Current Activity
↓
onPause()
Or:
Incoming phone call
↓
onPause()
onPause() should be fast.
Typical tasks:
- Pause animations
- Pause camera
- Commit lightweight changes
- Stop exclusive resources
Avoid lengthy operations because the next Activity is waiting for yours to pause.
10. onStop()
The Activity is no longer visible.
Home Button
↓
onPause()
↓
onStop()
Now is a good time to:
- Release larger resources
- Stop UI updates
- Unregister listeners tied to visibility
- Stop observing data that isn’t needed in the background
The Activity object may still exist in memory.
11. onRestart()
If the Activity was stopped but not destroyed, returning to it triggers:
onRestart()
↓
onStart()
↓
onResume()
This gives you a chance to prepare the Activity before it becomes visible again.
12. onDestroy()
This is the final callback before the Activity instance is destroyed.
Reasons include:
- User finishes the Activity
- Configuration change (like rotation)
- Android removes the Activity
Use it to clean up resources owned by the Activity.
Important: Do not rely on onDestroy() always being called. If the entire process is killed by the system, onDestroy() may never execute.
13. What Happens During Screen Rotation?
One of Android’s most misunderstood behaviors.
Suppose the user rotates the device.
Many assume:
Rotate
↓
UI rotates
That’s not what Android normally does.
Instead:
Portrait Activity
↓
onPause()
↓
onStop()
↓
onDestroy()
↓
New Activity Instance
↓
onCreate()
↓
onStart()
↓
onResume()
Why?
Because resources change:
- Layouts
- Dimensions
- Drawables
- Language
- Orientation-specific resources
Recreating the Activity ensures everything is reloaded correctly.
14. Configuration Changes
Rotation is just one configuration change.
Others include:
- Language change
- Font scale
- Screen size
- Dark mode
- Locale
- UI mode
- Display density
Most configuration changes recreate the Activity so it can load the correct resources.
15. Activity Destruction vs Process Death
These are not the same.
Activity Destruction
Activity
↓
Destroyed
↓
Process Still Alive
Example:
You press Back.
Only that Activity is removed.
Process Death
Activity
↓
Process
↓
Everything Gone
Example:
Your app is in the background.
System needs RAM.
Android kills the entire process.
Later:
User returns
↓
Entire Process Starts Again
This is why relying only on in-memory variables is dangerous.
16. Saving UI State
Imagine the user types:
Username
↓
John
Then rotates the phone.
Without saving state:
Rotation
↓
Activity recreated
↓
EditText empty ❌
Android provides onSaveInstanceState().
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("username", username)
}
Restore it in onCreate():
val username = savedInstanceState?.getString("username")
17. ViewModel and Configuration Changes
Before ViewModel:
Rotate
↓
Activity Destroyed
↓
Data Lost
↓
Reload API
With ViewModel:
Rotate
↓
Activity Destroyed
↓
ViewModel Survives
↓
Activity Recreated
↓
Reuse Existing Data
This is one of the main reasons ViewModel exists.
We’ll dive deeply into ViewModel in a later module.
18. Lifecycle-Aware Components
Jetpack introduced lifecycle-aware APIs to reduce bugs.
Instead of manually managing every callback, components can observe the lifecycle.
For example, using repeatOnLifecycle with coroutines ensures collection only happens while the UI is in an active state:
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state ->
// Update UI
}
}
}
This prevents leaks and unnecessary work when the Activity isn’t visible.
19. Common Lifecycle Bugs
Bug 1: Duplicate API Calls
onCreate()
↓
API Request
↓
Rotate
↓
New onCreate()
↓
Another API Request
Solution:
Move data loading to the ViewModel and cache results appropriately.
Bug 2: Memory Leak
Holding a reference to the Activity after it’s destroyed:
Singleton
↓
Activity Reference
↓
Activity Destroyed
↓
Reference Still Exists ❌
The garbage collector can’t reclaim the Activity.
Bug 3: Lost State
Rotate
↓
Activity Destroyed
↓
Counter = 0
Use savedInstanceState for transient UI state and ViewModel for screen-related data.
Bug 4: Updating a Dead Activity
Network Request
↓
Activity Destroyed
↓
Response Arrives
↓
Crash
Lifecycle-aware coroutines and proper scoping (e.g., viewModelScope, lifecycleScope) help prevent this.
20. Real-World Example
Imagine a YouTube-like app.
User opens video
↓
onCreate()
↓
Load player
↓
onStart()
↓
Show controls
↓
onResume()
↓
Video plays
↓
Home button
↓
onPause()
↓
Pause playback
↓
onStop()
↓
Release rendering resources
↓
User returns
↓
onRestart()
↓
onStart()
↓
onResume()
↓
Resume playback
Notice how each callback has a specific responsibility.
Best Practices
- Keep
onCreate()focused on initialization. - Use
onStart()/onStop()for work tied to visibility. - Use
onResume()/onPause()for work requiring user interaction (camera, sensors, animations). - Never perform heavy work on the main thread.
- Assume your Activity can be destroyed at any time.
- Use
ViewModelfor screen data that should survive configuration changes. - Use
savedInstanceStatefor temporary UI state (e.g., scroll position, text input). - Prefer lifecycle-aware APIs over manual callback management.
Mental Model
Instead of memorizing callbacks, remember this story:
Android creates your Activity
│
▼
Initialize everything (onCreate)
│
▼
Make it visible (onStart)
│
▼
Allow user interaction (onResume)
│
▼
Temporarily lose focus (onPause)
│
▼
Become invisible (onStop)
│
▼
Possibly return (onRestart)
│
▼
Eventually be destroyed (onDestroy)
If you understand why each transition happens, you’ll rarely need to memorize the order.
Interview Questions
- Why does Android use an Activity lifecycle instead of a
main()method? - Explain the difference between
onPause()andonStop(). - What happens internally when the device is rotated?
- How does
ViewModelhelp during configuration changes? - What’s the difference between Activity destruction and process death?
- Why shouldn’t you rely on
onDestroy()for critical cleanup? - When should you use
savedInstanceStateversus aViewModel? - What kinds of work belong in
onResume()but notonCreate()? - Why are lifecycle-aware APIs like
repeatOnLifecyclerecommended? - Describe a real-world lifecycle bug you’ve encountered or how you’d prevent one.
Up Next: Module 6 – Fragments (Deep Dive)
This won’t just be “Fragments are reusable UI.” We’ll cover:
- Why Google introduced Fragments
- The relationship between Activities and Fragments
- The complete Fragment lifecycle (and how it differs from Activity)
onCreateView()vsonViewCreated()- Why
onDestroyView()is one of the most important callbacks - FragmentManager and Fragment transactions
- Navigation Component and modern Fragment usage
- Common Fragment memory leaks and lifecycle pitfalls
- Why many modern Compose apps use a single-Activity architecture, and where Fragments still fit today
By the end, you’ll understand not only how to use Fragments, but also when they are the right architectural choice.