Module 5 of 20

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 ViewModel for screen data that should survive configuration changes.
  • Use savedInstanceState for 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

  1. Why does Android use an Activity lifecycle instead of a main() method?
  2. Explain the difference between onPause() and onStop().
  3. What happens internally when the device is rotated?
  4. How does ViewModel help during configuration changes?
  5. What’s the difference between Activity destruction and process death?
  6. Why shouldn’t you rely on onDestroy() for critical cleanup?
  7. When should you use savedInstanceState versus a ViewModel?
  8. What kinds of work belong in onResume() but not onCreate()?
  9. Why are lifecycle-aware APIs like repeatOnLifecycle recommended?
  10. 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() vs onViewCreated()
  • 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.