Activities & Lifecycle
๐ Activities & Lifecycle
๐ผ๏ธ What an Activity Is
An Activity represents one screen with a UI โ MainActivity is the one launched when the app icon is tapped, declared as such in AndroidManifest.xml (Chapter 1) via an intent filter. setContentView(R.layout.activity_main) is the line that actually connects this Kotlin class to the XML layout file it displays โ without it, the Activity exists but shows nothing.
super.onCreate(savedInstanceState) has to be the first line of an overridden onCreate โ it runs the base Android framework setup this Activity depends on. Skipping it, or calling it late, causes a crash. This applies to every lifecycle callback covered in this chapter, not just onCreate.
๐ The Lifecycle Callbacks
An Activity moves through a defined sequence of states as the user (or the system) interacts with it, and Android calls a specific method at each transition:
Each Callback, Plainly
| Callback | Fires when... |
|---|---|
| onCreate | The Activity is first created โ one-time setup (setContentView, initializing views) |
| onStart | The Activity becomes visible (but not yet interactive) |
| onResume | The Activity is now in the foreground and interactive โ the user can tap things |
| onPause | Losing focus, but still (partially) visible โ e.g. a dialog appears over it |
| onStop | No longer visible at all โ e.g. user pressed Home, or navigated to another Activity |
| onDestroy | Being permanently removed โ user pressed Back, or the system reclaimed memory |
Rotating the device, pressing Home, receiving a phone call mid-app, or the system simply needing memory back can all trigger these transitions โ often onPause/onStop followed later by onDestroy with no user action that looks like "closing the app" at all from their perspective.
vs the Web: No "Onload/Onunload" Equivalent Guarantee
| Browser Page | Android Activity | |
|---|---|---|
| Typical lifetime | Loads once, stays alive until tab closes | Created/destroyed repeatedly during normal use |
| Rotation/resize | CSS reflow only โ JS state untouched | Can fully recreate the Activity from scratch by default |
| Backgrounding | Tab keeps running (usually) | onStop then likely onDestroy if memory is needed |
This is the single biggest mental shift coming from web development: a browser tab's JavaScript state is a comparatively stable, long-lived thing. An Activity's Kotlin state is not โ by default, rotating the screen destroys and recreates the entire Activity, which is exactly why the next section matters.
๐พ savedInstanceState โ Surviving Recreation
Before destroying an Activity for a recoverable reason (like rotation, not like the user pressing Back), Android calls onSaveInstanceState, giving a chance to stash small bits of UI state into a Bundle โ which then comes back as the savedInstanceState parameter in the next onCreate:
This is deliberately for small, transient UI state (a scroll position, a form field's current text, a counter like above) โ not a substitute for real persistence. Anything that needs to survive the app being fully closed and relaunched later belongs in a database or file (covered in a later course), not a Bundle.
The savedInstanceState?.getInt(...) null-safe call above matters: savedInstanceState is null when the Activity is starting completely fresh (first launch, or after the user explicitly closed it) โ the safe-call plus Elvis operator pattern from Kotlin Fundamentals Chapter 3 is exactly what handles both cases correctly in one line.
๐ Logcat โ Watching It All Happen
Log.d(...) (and its siblings Log.i, Log.w, Log.e) writes to Logcat โ Android's equivalent of console.log, viewable in Android Studio's Logcat panel (Chapter 1) while the app runs:
The first argument is a tag โ conventionally the class name โ which Logcat's search bar can filter by, letting a specific Activity's output be isolated out of the constant stream of system-level log noise every Android app produces. Running the lifecycle example above and rotating the emulator is genuinely the best way to internalize the callback order โ watching onPause โ onStop โ onDestroy โ onCreate โ onStart โ onResume scroll past in Logcat makes the abstract sequence concrete.
๐ป Coding Challenges
Challenge 1: Logging Every Lifecycle Callback
Add the six lifecycle overrides from this chapter (onCreate through onDestroy) to MainActivity, each with a Log.d call using a consistent tag. Run the app, watch Logcat, then rotate the emulator (Ctrl+F11/F12, or the rotate button in the emulator toolbar) and observe which callbacks fire in what order.
Goal: See the lifecycle sequence happen for real, not just read about it.
Challenge 2: Surviving Rotation with savedInstanceState
Add a private var clickCount: Int = 0 to MainActivity, a Button in the layout that increments and logs it on click, and the onSaveInstanceState/onCreate pair needed to restore clickCount after rotation. Click the button several times, rotate the device, and confirm (via Logcat) the count survived.
Goal: Practice the actual save/restore round trip, not just writing the two methods in isolation.
Challenge 3: Reading a Real Logcat Filter
With the app from Challenge 1 running, use Logcat's search/filter bar to show only logs with your chosen tag, then separately filter to show only "Warn" level and above. Write a short comment describing what each filter changed about the visible output.
Goal: Get comfortable filtering Logcat's noisy default output down to what's actually relevant.
"Why did my data disappear when I rotated the phone?" is one of the most common early Android bugs, and it's a direct consequence of not internalizing this chapter. The lifecycle isn't an edge case to occasionally worry about โ it's the normal, constant background rhythm every Activity lives inside.
๐ฏ What's Next
Next chapter: XML Layouts & Views โ LinearLayout/ConstraintLayout, common Views, and view binding.