Understanding Activity Lifecycle In Android Apps

An Android activity represents a screen or focused user task, but it does not remain active forever. The operating system can pause it when another screen appears, stop it when the user leaves, or destroy it when resources are needed. Understanding these transitions helps developers build apps that feel stable, responsive and predictable.

The activity lifecycle also explains why data can disappear after a rotation, why network requests may continue after a screen closes, and why a video or camera preview should not keep running in the background. Once lifecycle callbacks are connected to suitable architecture, an app can handle interruptions without wasting battery or confusing users.

What The Lifecycle Represents

The lifecycle is the sequence of states through which an activity moves from creation to removal. Android calls specific methods during these transitions, giving the application opportunities to prepare the interface, begin visible work, pause interactive features and release resources.

A screen may be created once and revisited several times, or it may be destroyed and rebuilt after a configuration change. A user opening a message, receiving a phone call or switching to another app can trigger state changes. The operating system remains in control, so code should never assume that an activity will stay alive until the user explicitly closes it.

For developers working on Android apps for the Australian market, this matters during everyday situations such as moving between a Sydney train platform and underground coverage, locking a phone during a Melbourne coffee stop, or switching quickly between a banking app and a digital wallet.

The Core Lifecycle Callbacks

onCreate() runs when Android creates the activity. It is the normal place to inflate a layout, initialise view binding, read initial arguments and configure one-time dependencies. It should not contain lengthy operations on the main thread because slow work can make the interface appear frozen.

onStart() means the activity is becoming visible, while onResume() means it is ready for user interaction. Camera previews, location updates and animation that require an active foreground screen commonly begin or resume around these stages. When focus is lost, onPause() runs; when the activity is no longer visible, onStop() follows.

onRestart() is called when a stopped activity is becoming visible again. onDestroy() may run when the activity is finishing or being recreated, although Android can terminate a process without calling it. For that reason, critical data should never rely exclusively on onDestroy() for saving.

Saving State Through Recreation

Screen rotation, window resizing, language changes and dark mode can cause an activity to be recreated. The original instance is removed and a new one is built, which means values held only in ordinary properties can vanish. A search phrase, selected tab or partially completed form needs a deliberate state strategy.

onSaveInstanceState() can preserve small, temporary values in a Bundle, while a ViewModel retains UI-related state across configuration changes. For longer-term information, use a database, repository or other persistent store. Saved state is intended for short-lived restoration, not for storing large files or a complete application cache.

Modern Android projects often combine a ViewModel with SavedStateHandle. This separates screen state from the activity object and makes recreation less surprising. A lifecycle-aware observable, such as LiveData or a Kotlin StateFlow, can deliver updates only while the interface is in a suitable state.

Choosing The Right Lifecycle Location

Every callback has a different purpose. Placing work in the wrong method can cause duplicate requests, unnecessary battery use or an interface that does not refresh when the user returns.

Task Suitable lifecycle point Key consideration
Inflate views and read intent data onCreate() Perform setup once per activity instance
Start visible UI observation onStart() The screen is visible but may not have focus
Resume camera, sensors or animations onResume() Release or pause promptly when focus is lost
Pause interactive foreground work onPause() Keep this callback fast
Stop expensive visible-only work onStop() The activity is no longer visible
Retain screen state ViewModel and saved state Do not depend on onDestroy()

A music player may continue playback while its activity is stopped because playback belongs in a separate service or media controller. A barcode scanner, however, should generally stop using the camera as soon as the screen is paused. The right decision depends on whether the work belongs to the screen or to the wider application.

Developers can find broader Android explanations and examples in this Android learning resource, then apply the same principles to activities, fragments and navigation destinations.

Avoiding Leaks And Duplicate Work

A common error is registering a listener in onCreate() and never unregistering it. Location callbacks, broadcast receivers, text watchers and event subscriptions can retain an activity after it should be removed. The result may be memory pressure, duplicated events or updates sent to an invisible screen.

Use lifecycle-aware APIs where possible. repeatOnLifecycle(Lifecycle.State.STARTED) is useful with Kotlin coroutines and flows because collection stops when the interface is no longer visible. For manually managed resources, pair registration and cleanup deliberately, such as starting in onStart() and stopping in onStop().

Network calls also need careful handling. A request launched directly from an activity can finish after the user navigates away. A repository and ViewModel can own the operation, while the activity observes the result and updates views only when it is active.

Lifecycle Patterns In Modern Android

Jetpack Compose changes how developers think about screens, but lifecycle principles remain. Composables can enter and leave composition independently of an activity. LaunchedEffect, DisposableEffect and lifecycle observers help coordinate work with the visible UI, while state holders prevent business logic from being tied to a particular composition.

Fragments add another layer because a fragment has its own lifecycle and a separate view lifecycle. Code that touches fragment views should normally use viewLifecycleOwner, especially when collecting flows. Otherwise, an old view can remain referenced after the fragment itself continues to exist.

Navigation components also create transitions that are easy to overlook. A destination may remain on the back stack while its view is stopped. Testing STARTED and RESUMED behaviour helps reveal whether an observer is active at the expected time instead of assuming every destination is permanently visible.

Testing On Australian Devices And Networks

Lifecycle bugs often appear only under real interruptions. Test rotation, split-screen mode, backgrounding, process recreation, incoming calls, permission dialogs and returning from the launcher. Android Studio’s configuration tools are useful, but a physical device exposes timing and memory conditions that an emulator may miss.

The Australian Android market includes widely used Samsung Galaxy and Google Pixel models, along with budget phones from brands such as Motorola and OPPO. Check different Android versions, screen sizes and memory limits rather than relying on a single flagship handset. A user in regional Queensland, Western Australia or Tasmania may also experience slower or intermittent connectivity, making retained state especially important.

Run tests during practical workflows: a commuter changes trains in Sydney, a shopper loses reception in a large Melbourne centre, or someone pauses an app while paying at a contactless terminal. These scenarios expose screens that reload unnecessarily, submit forms twice or fail to restore progress after the app returns.

Use Espresso, Compose UI tests and lifecycle-aware unit tests to verify state transitions. Log callback events during development, but remove sensitive information before release. A clear test matrix should cover creation, foreground entry, temporary interruption, backgrounding, recreation and final removal.

A reliable activity respects the operating system’s decisions instead of fighting them. Keep transient UI state in suitable state holders, release screen-bound resources promptly and place durable work outside the activity when required. Apply these patterns to your next Android screen, test it across real devices and interruptions, and make lifecycle handling part of every release checklist.