Understanding Android Activity Lifecycle
If you’ve just started developing Android apps, you’ve almost certainly used an Activity. It’s the component responsible for showing a single screen that a user can interact with.
But an Activity is more than just a file where you put your UI code. It has a complex life cycle, a set of states it moves through from the moment it’s “born” (created) to when it’s “dead” (destroyed).
When developing Android applications, one of the most fundamental concepts every developer must understand is the Activity Lifecycle. Whether you’re building a simple to do app or a complex enterprise system, knowing how activities are created, paused, resumed, or destroyed is key to delivering smooth user experiences and preventing memory leaks.
Why is this so important?
Android is a mobile operating system, which means resources like memory and battery are limited. The OS can (and will) destroy and recreate your app’s components to save resources or handle configuration changes (like rotating the screen).
If you don’t understand the lifecycle, you’ll end up with:
- App crashes.
- Users losing their data (like text they typed in a form).
- Battery-draining processes running in the background. In this post, we’ll break down the Android Activity Lifecycle, one method at a time, with a simple code example you can run yourself.
Activity Lifecycle Overview

The entire lifecycle can be visualized with a simple flowchart. This diagram is a “rite of passage” for Android developers.
As you can see, the Activity moves between different states through a series of callback methods. Your job is to override these methods to perform the right actions at the right time.
Lifecycle Flow Explained
Let’s break down what happens at each stage:
1. onCreate()
- Called when: The activity is first created.
- Purpose: Initialize essential components, set the layout, bind views, and prepare resources.
- Example:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("Lifecycle", "onCreate called")
}
2. onStart()
- Called when: The activity becomes visible to the user but not yet in the foreground.
- Use it for: Starting animations, refreshing UI elements, or preparing the app to enter the foreground.
- Example:
override fun onStart() {
super.onStart()
Log.d("Lifecycle", "onStart called")
}
3. onResume()
- Called when: The activity comes to the foreground and the user can interact with it.
- Use it for: Starting sensors, listeners, or media playback.
Example:
override fun onResume() {
super.onResume()
Log.d("Lifecycle", "onResume called")
}
4. onPause()
- Called when: The activity is partially obscured (e.g., user opens a dialog or switches apps).
- Use it for: Pausing animations, saving unsaved data, or stopping camera/sensor updates.
Example:
override fun onPause() {
super.onPause()
Log.d("Lifecycle", "onPause called")
}
5. onStop()
- Called when: The activity is no longer visible.
- Use it for: Releasing heavy resources like network connections or database handles.
Example:
override fun onStop() {
super.onStop()
Log.d("Lifecycle", "onStop called")
}
6. onRestart()
- Called when: The activity is being restarted after being stopped.
- Use it for: Re-initializing components that were released during onStop().
Example:
override fun onRestart() {
super.onRestart()
Log.d("Lifecycle", "onRestart called")
}
7. onDestroy()
- Called when: The activity is finishing or being destroyed by the system.
- Use it for: Final cleanup, releasing resources, or saving persistent data.
- Example:
override fun onDestroy() {
super.onDestroy()
Log.d("Lifecycle", "onDestroy called")
}
Visual Representation
Here’s how the lifecycle typically flows:
Example Use Case: Saving App State
Imagine a user typing something in a form, then switching apps. If we don’t handle the lifecycle properly, their input might be lost.
Solution: Save the input during onPause() and restore it in onResume().
private var userInput: String? = null
override fun onPause() {
super.onPause()
userInput = editText.text.toString()
}
override fun onResume() {
super.onResume()
editText.setText(userInput)
}
The “Logcat” Example
The single best way to understand the lifecycle is to see when each method is called. Create a new, empty Android project in Kotlin and update your MainActivity.kt file with the following code.
The only thing this code does is log a message every time a lifecycle method is triggered.
package com.example.lifecycleapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
class MainActivity : AppCompatActivity() {
// Define a consistent tag for logging
private val TAG = "LifecycleDemo"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d(TAG, "onCreate called")
}
override fun onStart() {
super.onStart()
Log.d(TAG, "onStart called")
}
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume called")
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause called")
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop called")
}
override fun onRestart() {
super.onRestart()
Log.d(TAG, "onRestart called")
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy called")
}
}
Now, run your app and open the Logcat panel in Android Studio. Filter the logs by our LifecycleDemo tag. As you use your phone, you’ll see these messages appear in real-time!
Scenarios in Practice
Let’s test our app. Watch your Logcat while you do the following:
Scenario 1: Fresh App Launch
You open the app for the first time.
D/LifecycleDemo: onCreate called
D/LifecycleDemo: onStart called
D/LifecycleDemo: onResume called
Scenario 2: Pressing the Home Button
You leave the app. The Activity is no longer visible.
D/LifecycleDemo: onPause called
D/LifecycleDemo: onStop called
Scenario 3: Returning to the App
You open the app again from the “recents” list.
D/LifecycleDemo: onRestart called
D/LifecycleDemo: onStart called
D/LifecycleDemo: onResume called
Scenario 4: Pressing the Back Button
You press “Back” to exit the app completely.
D/LifecycleDemo: onPause called
D/LifecycleDemo: onStop called
D/LifecycleDemo: onDestroy called
(The Activity is now finished. If you open it again, onCreate() will be called).
Scenario 5: The “Surprise” – Rotating the Screen
This is the one that surprises all new developers. Turn on auto-rotate and tilt your phone.
D/LifecycleDemo: onPause called
D/LifecycleDemo: onStop called
D/LifecycleDemo: onDestroy called
D/LifecycleDemo: onCreate called
D/LifecycleDemo: onStart called
D/LifecycleDemo: onResume called
That’s right—by default, rotating the screen destroys and recreates your entire Activity! This is to allow the app to load different layouts for portrait and landscape.
This is why it’s so important to not do heavy work in onCreate() and to properly save and restore your state (using ViewModel and savedInstanceState).
💡Tips for Developers
- Always release resources like camera, GPS, or media players in onPause() or onStop().
- Avoid performing heavy operations in onCreate().
- Use ViewModel or savedInstanceState to preserve UI data across configuration changes (like screen rotation).
- Log lifecycle methods during debugging to better understand activity behavior.
🏁 Conclusion
The Activity Lifecycle isn’t just theory; it’s the fundamental set of rules for building stable, professional, and resource-friendly Android applications.
By understanding when your code runs, you can ensure your user’s data is always safe, your app doesn’t drain their battery, and it doesn’t crash during common events like a phone call or a simple screen rotation.
Happy coding! Deenadhayaalna M
