ONE family skill covering iOS, Android, Flutter, and React Native with per-framework references (ios.md, android.md, flutter.md, react-native.md), shared scaffold/build/sign/test/ship workflow, mobile lifecycle, offline and sync guidance, and mobile-specific testing. Ships a 5-heading human README and a schema-v1 eval manifest with 6 cases covering build/sign, testing, and store-readiness. Adds the README index entry and regenerates catalogs. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
8.3 KiB
Android Reference — Kotlin, Gradle, Google Play
Last Updated: 2026-08-03
Load this reference when the target platform is Android — native Kotlin
apps built with Gradle, or an Android target inside a Flutter or React Native
project (tooling for those is in flutter.md and
react-native.md; this file is the platform layer under
them). It complements the shared workflow in SKILL.md; this file is the
Android-specific detail for scaffolding, building and signing, emulator and
device testing, and Play Store submission.
Android fundamentals
An Android app is a compiled, signed package built by Gradle:
- Gradle project — a project root with
settings.gradle(.kts), anappmodule withbuild.gradle(.kts), andgradle/libs.versions.tomlfor version catalog dependency management. Kotlin DSL (.kts) is the current default. - Manifest —
AndroidManifest.xmldeclares the application, activities, services, receivers, permissions, and the minimum/target SDK. - Build outputs —
assembleDebug/assembleReleaseproduce APKs;bundleReleaseproduces an Android App Bundle (AAB), the required submission format for new apps on Google Play (since 2021, and still the rule). Google Play derives per-device APKs from the AAB via Play App Signing. - Gradle wrapper — commit
gradlewandgradle/wrapper/so builds use a pinned Gradle version on every machine and CI runner.
Keep the version name (versionName) and version code (versionCode, a
monotonic integer) in build.gradle.kts — Play rejects a build whose version
code is lower than a previous upload.
Scaffolding
- New native app — create the project in Android Studio or with the Gradle
template (
gradle init); choose Kotlin and Jetpack Compose for new UI. - Minimum and target SDK — set
minSdkto the oldest Android version in scope and keeptargetSdkcurrent; Play enforces minimum target API levels for new and updated submissions, and raised target levels are announced annually. - Dependencies — prefer version catalogs (
libs.versions.toml) and commit the lockfile (gradle.lockfileor dependency locking) for reproducibility. - App structure — a single-activity app with Compose navigation for new work; keep the manifest minimal and declare only the permissions the app actually uses.
Builds and signing
Signing model
- Local signing — a Java keystore (
.jks/.keystore) with an alias, configured viasigningConfigsinbuild.gradle.kts. Signing configs must never be committed with their passwords; read them from environment variables or a secrets store at build time. - Play App Signing — Google holds the app signing key; the upload key you sign with is only used to upload the AAB to Play. Upload keys can be rotated without user-visible changes; losing the upload key requires Play Console support intervention.
- Keystore custody — the release keystore is a production secret: back it up, store it outside the repository, and restrict access. Losing it means the app can no longer be updated under the same identity.
Signing practices
- Debug builds sign automatically with the debug keystore — never ship them.
- Release builds in CI — inject keystore path, passwords, and aliases via
CI secrets; keep
keystore.properties(or equivalent) out of version control. UsesigningConfigreferenced from a file that CI can generate. - Two build types —
debugandreleasediffer in signing, shrinking (R8/ProGuard), and manifest merging. Smoke-test the signed release artifact, not just the debug build.
Build commands
# Debug APK (fast iteration)
./gradlew assembleDebug
# Release APK (signed, shrunk)
./gradlew assembleRelease
# Release App Bundle (required for Play Store submission)
./gradlew bundleRelease
The AAB lives in app/build/outputs/bundle/release/; the signed APK in
app/build/outputs/apk/release/. Verify the APK signature with
apksigner verify --print-certs app-release.apk before distribution.
Emulators and devices
-
Emulators (AVD) — Android Studio AVD Manager creates virtual devices; headless emulators are scriptable for CI:
emulator -avd Pixel_8 -no-window -no-audio -no-boot-anim & adb wait-for-device adb install app/build/outputs/apk/debug/app-debug.apk adb shell am start -n com.example.app/.MainActivity -
Physical devices — enable USB debugging and use
adb devicesto verify the connection; real devices reveal networking, battery, and sensor behavior the emulator hides. -
Debugging —
adb logcatfor logs,adb shell dumpsysfor system state, and Android Studio Profiler for CPU/memory/network.adb reversemaps device ports to the host for local API servers. -
Device matrix — cover the min SDK, the current SDK, and a mid-range device; use Firebase Test Lab (or a farm) for broad matrix coverage without local hardware.
Lifecycle and backgrounding
- Component lifecycle — Activities/Fragments move through
started/paused/stopped states; ViewModels survive configuration changes and
should own UI state.
Process deathcan destroy everything else. - State persistence — save and restore instance state (
SavedStateHandle,rememberSaveablein Compose) for process death; persist anything important to a durable store. - Background work is restricted — Android restricts background execution
and network. Use
WorkManagerfor deferrable, guaranteed work, and foreground services (with a visible notification) only for user-visible tasks.AlarmManageris for alarms, not general scheduling. - Doze and app standby — the system batches background work when idle; test offline sync and push handling under Doze, not just with the screen on.
Offline and sync
- Local persistence — Room (SQLite ORM) for structured data, DataStore (Preferences/Proto) for settings, and file storage under the app's internal/external storage. Keep the database schema versioned with migrations tested.
- Sync pattern — write locally, then sync: queue writes, replay them with
retry and backoff when connectivity returns, and resolve conflicts
explicitly.
WorkManagerwith network constraints is the idiomatic sync trigger. - Connectivity — use
ConnectivityManager/NetworkCallback to observe connectivity, but design for a lost network degrading gracefully.
Testing
- Unit tests — JUnit + MockK/mockito for logic; Robolectric runs Android-framework code on the JVM for fast local tests.
- Instrumented/UI tests — Espresso (Views) or Compose UI tests
(
createAndroidComposeRule) drive the real app on an emulator/device. - Snapshot tests — Compose Preview-based snapshot testing (e.g., Roborazzi, Paparazzi) catches UI regressions without a device.
- Device farms — run the instrumentation suite on Firebase Test Lab across the device matrix; a test passing on one API level is not a guarantee across them.
Store submission
- Play Console setup — the $25 developer account, app record, and developer verification (new developers complete identity verification and a closed-test requirement with at least 12 testers for 14 days before production access).
- Upload the AAB — upload
app-release.aabto an internal, closed, or open testing track first; run internal testing with your own devices before production. Play generates and signs per-device APKs via Play App Signing. - Store listing and policies — screenshots, feature graphic, privacy policy URL, and a data safety declaration matching what the app collects. Play policy review rejects apps for undeclared data collection, broken core functionality, and misleading metadata.
- Staged rollout — use phased rollouts (e.g., 10% → 50% → 100%) and monitor crash and ANR rates in Play Console before full release. Pause the rollout immediately if a serious regression appears.
Key references
- Google Play Console help and policy center (support.google.com/googleplay) — current data-safety and testing-track requirements.
- Android developer documentation (developer.android.com) — target API level deadlines and app bundle guidance change annually.