Modern Android Development

Last update: 2026-02-10 13:57:26 +0800 +0800
Available translations: 日本語 / 中文(简体) / 中文(繁體)

Modern Android applications commonly use Kotlin, AndroidX, Jetpack libraries, and Jetpack Compose. Platform APIs remain in android.*; AndroidX supplies version-compatible and higher-level APIs in androidx.*. An application package has multiple system-managed entry points rather than a conventional process-wide main() method.

Application Isolation #

Android assigns an installed package a Linux UID and gives its private files UID-based ownership. An application process runs its own Android Runtime instance, and cross-package component calls use Binder IPC. Runtime permissions, SELinux, and framework service checks supplement the UID boundary.

Shared UIDs were once available to equally signed packages but are deprecated for new applications because they weaken package isolation. Applications share data through explicit interfaces, such as a permission-protected content provider, document picker, URI grant, or Binder service, rather than through private paths.

Components and the Manifest #

Android has four component types:

  • An activity hosts a focused user interface.
  • A service performs work without an activity UI. Long-running user-visible work requires a foreground-service notification and is subject to platform limits.
  • A broadcast receiver performs a short response to a broadcast and should delegate lengthy work to an appropriate scheduler.
  • A content provider exposes structured data through a ContentResolver API.

The manifest declares application components, permissions, package visibility where needed, minimum SDK level, features, and application metadata. A component with an intent filter is externally addressable only if its android:exported setting and the applicable permissions permit it. Keep non-public components unexported.

Intents and Component Activation #

An explicit intent identifies a particular component. An implicit intent describes an action, data, categories, and optional extras; the system resolves it against exported intent filters. Use explicit intents for internal operations and services, because an implicit service intent can resolve to an unintended component.

Activities launch through startActivity or the Activity Result APIs. Services use startService, startForegroundService, or bindService according to their execution model. Content providers receive operations through ContentResolver. Background work that does not need immediate execution belongs in WorkManager or, where appropriate, JobScheduler rather than a long-lived background service.

Treat all incoming intents, extras, and URIs as untrusted input. Verify callers where the API permits it, validate values, require permissions for sensitive components, and grant URI permissions only as narrowly and briefly as required.

Activity Lifecycle and State #

The system creates an activity with onCreate, makes it visible through onStart, and makes it interactive through onResume. onPause indicates that the activity has lost foreground focus; it must return quickly. onStop follows when the activity is no longer visible and is the appropriate place to release resources needed only while visible.

An activity object can be destroyed because finish was requested or because the system reclaims its process. onSaveInstanceState stores small, reconstructible UI state for the latter case. The framework saves supported view-hierarchy state, but application state belongs in a ViewModel, saved-state handle, database, or other durable store according to its size and lifetime. Do not use a lifecycle callback to perform an unbounded network transaction or database migration.

Resources #

The Android resource system compiles res/ entries into generated identifiers such as R.string.app_name. Place each resource in a typed top-level directory, such as layout, drawable, mipmap, values, xml, font, menu, raw, anim, or animator. Assets placed in assets/ are not compiled into R and are opened through AssetManager.

Resource qualifiers select the most appropriate alternative for configuration, locale, screen size, density, orientation, and night mode. Qualifiers must use the documented order and may not repeat a qualifier type. Keep a default resource for every resource the application references, because a device configuration might not match a specialized alternative.

Kotlin, Jetpack, and Compose #

Kotlin supplies null safety, extension functions, lambdas, sealed types, and coroutines. AndroidX and Jetpack provide lifecycle-aware components, Navigation, Room, WorkManager, and compatibility APIs. lifecycleScope and viewModelScope tie coroutines to their owners, but cancellation does not remove the need to make work idempotent and to handle failures.

Jetpack Compose expresses UI as composable functions. An activity enters Compose with setContent; observable state collected into the composition causes the affected UI to recompose. LazyColumn provides efficient item-based layouts, and modifiers express layout, interaction, and decoration.

Keep screen state in a ViewModel, make composables primarily functions of state, and use effect APIs for work whose lifetime depends on composition. Views and Compose can interoperate during a staged migration, so a rewrite is not required to adopt Compose.

Comments

Read or comment on GitHub (sign-in required to comment)