Compose hides much of Android, but every app still sits on the same foundation. You need it to debug lifecycle problems, handle links and notifications, and pass interviews.
The four app components
- Activity: one screen with a window. Modern apps often have a single Activity that hosts all Compose screens.
- Service: work that runs without a screen. A *foreground service* shows a notification and is used for music, navigation or uploads.
- BroadcastReceiver: reacts to system or app messages, such as boot completed or battery low.
- ContentProvider: shares structured data between apps, as the Contacts and Media stores do.
All components are declared in AndroidManifest.xml, together with permissions, the app icon and name, and intent-filters that say which links or actions a component can handle.
The Activity lifecycle
Android creates, pauses and destroys your Activity as the user moves around. The main callbacks are onCreate (set up, call setContent), onStart (becoming visible), onResume (in the foreground and interactive), onPause (losing focus), onStop (not visible) and onDestroy. Put start/stop work, such as listening for location, in the matching pair of callbacks, or better, use lifecycle-aware tools like collectAsStateWithLifecycle, which do it for you.
A configuration change, such as rotation, dark mode or a language switch, recreates the Activity by default. That is why state must live in a ViewModel or in rememberSaveable. The system can also kill your whole process while the app is in the background to free memory. Data that must survive that goes in SavedStateHandle, a database or DataStore.
Fragments
A Fragment is a reusable piece of UI with its own lifecycle that lives inside an Activity. Older apps use many Fragments with the Navigation Component. Its view has a separate lifecycle (onCreateView to onDestroyView), which is a common source of leaks: never keep a reference to the binding after the view is destroyed. In new Compose apps you rarely write Fragments, but you may maintain them.
Intents
An Intent is a message that asks the system to do something. An *explicit* intent names the target class. An *implicit* intent describes an action and lets Android pick an app.
// explicit: open another Activity of your own app
startActivity(Intent(this, DetailActivity::class.java).putExtra("id", 42))
// implicit: open a web page in whichever browser the user has
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com")))
// share text
val send = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "Look at this app")
}
startActivity(Intent.createChooser(send, "Share with"))
An intent-filter in the manifest lets your app receive such intents or open from a link (deep link). Since Android 12, any component with an intent filter must declare android:exported.
Permissions
*Normal* permissions (such as INTERNET) are granted at install. *Dangerous* permissions (camera, location, notifications, contacts) must be requested at run time, and the user can refuse. Use the Activity Result API, which Compose wraps as rememberLauncherForActivityResult.
val launcher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted -> if (granted) startCamera() else showExplanation() }
Button(onClick = { launcher.launch(Manifest.permission.CAMERA) }) { Text("Scan") }
Context and resources
A Context gives access to resources, files and system services. The application context lives as long as the app. An Activity context lives as long as the screen and carries its theme. Never store an Activity context in a long-lived object, because the Activity then cannot be freed: that is a memory leak. Resources live in res/: strings.xml for text (so you can translate it), drawable for images, values for colours and dimensions, and qualifiers such as values-hi or values-night give alternatives for languages and dark mode.
Navigation and the back stack
Each Activity or navigation destination is pushed on a back stack. The Back button pops it. The launchMode and navigation options such as popUpTo change this. Android 14 and later support predictive back, so avoid intercepting Back unless you must.
Your task
- Add log lines to every Activity lifecycle callback and watch the order when you open the app, press Home, rotate and return.
- Share text from your app with an implicit intent.
- Request the camera permission and handle both answers.
- Add a deep link to one screen in the manifest and open it with
adb shell am start -a android.intent.action.VIEW -d "myapp://item/1".
How to check it worked
- You can describe what happens to your state on rotation.
- You know which permissions are asked at run time.
- You can explain explicit and implicit intents.