Step 2 of 15
Activity lifecycle states, Fragment lifecycle, lifecycle-aware components
Activity และ Fragment lifecycle — เข้าใจว่าแต่ละ state เกิดอะไรขึ้น เพื่อเขียนโค้ดที่ไม่ crash
An Activity goes through states as the user navigates the app. Each state has a callback method you can override.
Diagram: The Activity lifecycle states and their transitions.
Loading diagram...
| Callback | When it runs |
|---|---|
onCreate() | Activity is first created. Set up UI here. |
onStart() | Activity becomes visible. |
onResume() | Activity is ready for user input. |
onPause() | Activity loses focus (partially hidden). |
onStop() | Activity is fully hidden. |
onDestroy() | Activity is destroyed. Clean up resources. |
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
class MainActivity : ComponentActivity() {
private val tag = "Lifecycle"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(tag, "onCreate")
}
override fun onStart() {
super.onStart()
Log.d(tag, "onStart")
}
override fun onResume() {
super.onResume()
Log.d(tag, "onResume")
}
override fun onPause() {
super.onPause()
Log.d(tag, "onPause")
}
override fun onStop() {
super.onStop()
Log.d(tag, "onStop")
}
override fun onDestroy() {
super.onDestroy()
Log.d(tag, "onDestroy")
}
}
Rotate the device and watch Logcat (filter by Lifecycle):
// Launch app:
// onCreate → onStart → onResume
// Rotate device:
// onPause → onStop → onDestroy → onCreate → onStart → onResume
Rotation destroys and recreates the Activity. This is why you must not keep state in the Activity itself — use a ViewModel instead.
Instead of overriding every callback, observe the lifecycle with DefaultLifecycleObserver. Your code stays clean and reusable.
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import android.util.Log
class MyObserver : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
Log.d("Observer", "Started — connect to server")
}
override fun onStop(owner: LifecycleOwner) {
Log.d("Observer", "Stopped — disconnect")
}
}
Attach it to an Activity:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(MyObserver())
}
}
The observer now runs its onStart/onStop automatically when the Activity changes state.
A Fragment lives inside an Activity. It has extra callbacks because it handles its own view creation:
| Fragment callback | Purpose |
|---|---|
onAttach() | Fragment is attached to its Activity |
onCreateView() | Create and return the Fragment's view |
onViewCreated() | View is ready — set up listeners |
onDestroyView() | View is being destroyed |
onDetach() | Fragment is detached |
In a Compose-only app, you rarely use Fragments directly. Compose handles UI state for you. But you will meet Fragments in older code or third-party libraries.
Add a DefaultLifecycleObserver that logs "Foreground" in onResume and "Background" in onPause. Press the Home button and return to the app. Confirm the log order is onPause → Background, then onResume → Foreground.