Android Dev

Production-grade Android app development guide covering native (Kotlin/Java), cross-platform (Flutter, RN, KMM), and hybrid architectures.

Published by @sickn33 and contributors·from sickn33/antigravity-awesome-skills·0 agent reads / 30d·0 saves·

Android App Development Skill

Overview

This skill guides production-grade Android and cross-platform (non-iOS) app development following practices used at big tech companies. It covers the entire development lifecycle — architecture, UI, code quality, testing, error handling, release, and maintenance.

When to Use This Skill

  • Use when deciding on a tech stack (see §1 Stack Selection)
  • Use when setting up project architecture (see §2 Architecture)
  • Use when designing UI, screens, or a design system (see §3 UI & Design)
  • Use when ensuring code quality, patterns, or APIs (see Best Practices)
  • Use when implementing error handling or debugging crashes (see §5 Error Handling)
  • Use when planning testing strategy (see §6 Testing)
  • Use when configuring build, CI/CD, or release pipelines (see §7 Build & Release)
  • Use when optimizing performance or memory (see §8 Performance)
  • Use when debugging or fixing bugs (see §9 Debugging)
  • Use when following the full development roadmap (see §10 Development Roadmap)
  • Use when needing deep reference for a stack (see references/ directory)

§1 Stack Selection

Choose based on team, requirements, and platform targets. Do not recommend iOS-specific paths.

Native Android — Kotlin + Jetpack Compose

Best for: Android-only apps, hardware-intensive features, best-in-class UX, new projects.

  • Language: Kotlin
  • UI: Jetpack Compose (modern declarative UI)
  • Key libs: Room, Retrofit/Ktor, Hilt, WorkManager, DataStore, Navigation Compose
  • Reference: references/native-android.md

Native Android — Java + XML Views

Best for: Existing Java codebases, teams without Kotlin experience, legacy app maintenance, incremental Kotlin migration.

  • Language: Java (fully supported by Google, not deprecated)
  • UI: XML Layouts (ConstraintLayout, RecyclerView, ViewBinding)
  • Key libs: Room, Retrofit, Hilt, WorkManager, LiveData, ViewModel
  • Java and Kotlin coexist seamlessly in the same project — migrate incrementally
  • Reference: references/java-android.md

Flutter (Dart)

Best for: Android + Web (+ desktop) from one codebase, fast iteration, pixel-perfect custom UI.

  • Language: Dart
  • UI: Flutter Widget tree (Material 3 / Cupertino widgets available but target Material for Android)
  • Key libs: Provider/Riverpod/Bloc, Dio, Drift/Isar, go_router, flutter_local_notifications
  • Reference: references/flutter.md

React Native (JavaScript/TypeScript)

Best for: Web + Android code sharing, JS/TS teams, rich ecosystem.

  • Language: TypeScript (preferred)
  • UI: React Native core components + NativeWind / React Native Paper
  • Key libs: React Navigation, Zustand/Redux Toolkit, React Query, MMKV
  • Reference: references/react-native.md

Kotlin Multiplatform (KMM / Compose Multiplatform)

Best for: Sharing business logic across Android + Desktop + Web while keeping native Android UI.

  • Language: Kotlin everywhere
  • UI: Native Compose on Android; Compose Multiplatform for shared UI
  • Key libs: Ktor, SQLDelight, Koin, kotlinx.serialization, Napier
  • Reference: references/kmm.md

Hybrid (Capacitor / Ionic)

Best for: Web-first teams, simple apps, PWA-like content apps.

  • Language: TypeScript + HTML/CSS
  • UI: Ionic components or custom web UI
  • Avoid for: Heavy animations, native sensor access, high-performance games
  • Reference: references/hybrid.md

Decision Matrix

RequirementNative KotlinNative JavaFlutterRNKMMHybrid
Android-only (new)✅ Best
Android-only (existing Java)⚠️ migrate✅ Best⚠️
Android + Web✅ Best
Android + Desktop⚠️⚠️
Shared business logic onlyN/AN/AN/AN/A✅ BestN/A
Native performance⚠️
JS/TS team✅ Best
Custom pixel-perfect UI⚠️✅ Best⚠️

§2 Architecture

Core Principle: Separation of Concerns

Every production Android project must separate UI, business logic, and data into distinct, independently testable layers.

Recommended Architecture: Clean Architecture + MVI/MVVM

app/
├── ui/              # Composables / Activities / Fragments / Screen states
├── presentation/    # ViewModels, UI State, UI Events
├── domain/          # Use cases, domain models, repository interfaces
├── data/            # Repository impl, remote (API), local (DB), mappers
└── di/              # Dependency injection modules

Data flow (unidirectional):

User Action → ViewModel/Store → Use Case → Repository → Data Source
                    ↓
             UI State (sealed class / StateFlow)
                    ↓
             Composable / View renders state

Key Architecture Patterns by Stack

Native (MVVM + MVI):

  • StateFlow / SharedFlow for reactive state
  • sealed class UiState + sealed class UiEvent
  • Hilt for DI, coroutines + Flow for async
  • Repository pattern wrapping Room + Retrofit

Flutter (BLoC or Riverpod):

  • Bloc or Cubit for business logic isolation
  • AsyncNotifierProvider (Riverpod) for data + state
  • Repositories as abstract classes with impl injected

React Native (Redux Toolkit or Zustand):

  • RTK Query or React Query for server state
  • Zustand slices for client state
  • Custom hooks to encapsulate business logic per feature

KMM:

  • Shared commonMain holds domain + data layers
  • expect/actual for platform-specific implementations
  • Kotlin coroutines + Flow bridged to platform (StateFlow on Android)

Module Structure (Multi-module for large apps)

:app            # Entry point, DI wiring
:core:ui        # Design system, shared composables
:core:network   # API client, interceptors
:core:database  # Room / SQLDelight setup
:feature:home
:feature:profile
:feature:settings

§3 UI & Design

Design System First

Before writing screens, define:

  1. Color tokens — Primary, secondary, surface, on-surface, error; light + dark variants
  2. Typography scale — Display, headline, title, body, label (Material 3 type system)
  3. Spacing scale — 4dp grid system (4, 8, 12, 16, 24, 32, 48dp)
  4. Shape tokens — Corner radii per component family
  5. Component library — Button, TextField, Card, BottomSheet, TopAppBar, etc.

Jetpack Compose UI Rules

  • Use MaterialTheme tokens; never hardcode colors/dimensions
  • CompositionLocal for theme, locale, haptics
  • remember / rememberSaveable correctly (saveable for UI state surviving rotation)
  • Extract large composables into sub-composables; each function ≤ 80 lines
  • Use LazyColumn/LazyVerticalGrid for lists; never Column with forEach for large data
  • Side effects only in LaunchedEffect, DisposableEffect, SideEffect
  • Avoid state hoisting anti-patterns: hoist state to the lowest common ancestor

Accessibility (Non-Negotiable)

  • All interactive elements: contentDescription or semantics { }
  • Min touch target: 48×48dp
  • TalkBack compatibility tested before every release
  • Dynamic text size support (sp not dp for text)
  • Color contrast ratio ≥ 4.5:1 (WCAG AA)

Navigation

  • Native: Navigation Compose with typed NavHost and SafeArgs equivalent
  • Flutter: go_router with named routes and guards
  • RN: React Navigation v7 with typed NavigationProp
  • Deep link handling registered for every screen that can be externally opened
  • Back stack managed deliberately — don't push duplicates, use popUpTo / launchSingleTop

Responsive & Adaptive UI

  • Support all screen sizes: phones, foldables, tablets (WindowSizeClass)
  • Test at 320dp, 360dp, 411dp, 600dp+, 840dp+ widths
  • Foldable hinge awareness via WindowInfoTracker
  • Edge-to-edge display + WindowInsets handling required for Android 15+

Best Practices

Language Standards

Kotlin:

  • Prefer data class, sealed class, object, enum class appropriately
  • No !! null assertions — use ?.let, ?: return, requireNotNull with message
  • Coroutines: always specify CoroutineScope + Dispatcher explicitly; never GlobalScope
  • Use @Stable / @Immutable on Compose state classes for smart recomposition

Java:

  • @NonNull / @Nullable annotations on every method param and return type
  • Never call methods on unchecked objects — null-check explicitly or use Objects.requireNonNull
  • Always null binding reference in Fragment's onDestroyView() to prevent memory leaks
  • Use ExecutorService (not AsyncTask — deprecated) for background work; or LiveData + Room's built-in threading
  • Prefer ListAdapter + DiffUtil over manual notifyDataSetChanged() in RecyclerView
  • Use ViewBinding — never findViewById

Dart (Flutter):

  • Null safety required — no ! without explicit null check above
  • Immutable state objects with copyWith
  • const constructors on all stateless widgets

TypeScript (RN):

  • strict: true in tsconfig always
  • Zod or io-ts for runtime type validation of API responses
  • No any — use unknown and narrow

Dependency Management

  • Pin all dependency versions in build.gradle.kts / pubspec.yaml / package.json
  • Audit dependencies monthly for security vulnerabilities
  • Avoid transitive dependency conflicts — use dependency resolution strategies
  • Keep dependency count minimal — every added lib is a maintenance burden

Code Review Checklist (PR gate)

  • New public APIs have KDoc / DartDoc / JSDoc
  • No hardcoded strings — use string resources / l10n
  • No hardcoded dimensions or colors outside design tokens
  • No blocking I/O on main thread
  • No memory leaks (no Activity context stored in singletons)
  • Coroutine scopes / streams properly cancelled / disposed
  • Feature flag guarding any non-trivial feature

§5 Error Handling

The Golden Rule

Never let exceptions propagate to the user silently or crash the app.

Error Classification

TypeStrategy
Network errorsRetry with exponential backoff; show retry UI
Auth errors (401/403)Refresh token → re-request → logout if fails
Validation errorsShow inline field errors immediately
Data parsing errorsLog + fallback to cached/default state
Unexpected crashesCatch at top-level; show error screen + report
Background task failuresRetry via WorkManager; notify user if critical

Result / Either Pattern (Kotlin)

sealed class AppResult<out T> {
    data class Success<T>(val data: T) : AppResult<T>()
    data class Error(val exception: AppException) : AppResult<Nothing>()
}

sealed class AppException(msg: String) : Exception(msg) {
    class NetworkException(msg: String) : AppException(msg)
    class AuthException(msg: String) : AppException(msg)
    class ParseException(msg: String) : AppException(msg)
    class UnknownException(msg: String) : AppException(msg)
}

Use AppResult<T> as return type for all repository + use case functions. ViewModels map to UiState.Error.

Crash Reporting

  • Integrate Firebase Crashlytics or Sentry from day one
  • Set user identifiers and custom keys before crash occurs
  • Non-fatal exceptions logged for all caught errors
  • ANR monitoring enabled
  • Crash-free sessions target: ≥ 99.5%

Offline / Network Resilience

  • Cache-first strategy: show stale data, fetch fresh in background
  • Room / Drift / MMKV as single source of truth
  • Expose network state via ConnectivityManager and reflect in UI
  • All network calls wrapped with timeout + retry policy

§6 Testing

Testing Pyramid

         /\
        /E2E\        ← 10%  (UI tests: Espresso, Maestro, Appium)
       /------\
      / Integr \     ← 20%  (Repository, DB, API contract tests)
     /----------\
    /    Unit    \   ← 70%  (ViewModels, Use Cases, Utilities)
   /--------------\

Unit Tests (70%)

  • Every ViewModel, UseCase, Repository, Mapper tested
  • Native: JUnit5 + MockK + Turbine (Flow testing) + Kotest assertions
  • Flutter: flutter_test + mocktail
  • RN: Jest + @testing-library/react-native + msw for API mocking
  • Coverage target: ≥ 80% on domain + presentation layers

Integration Tests (20%)

  • Room DB tests with in-memory database
  • Retrofit/Ktor tests with MockWebServer (OkHttp)
  • Repository tests verifying cache + remote coordination
  • API contract tests against real staging endpoint

UI / E2E Tests (10%)

  • Espresso for critical user journeys (login, checkout, core action)
  • Maestro for cross-platform E2E flows (recommended for Flutter + RN too)
  • Run on real device farm (Firebase Test Lab / BrowserStack) before release
  • Smoke test suite runs on every PR; full E2E suite nightly

Test Data Management

  • Use factories / builders for test data, never copy-paste objects
  • Hermetic tests: never share mutable state between test cases
  • Fakes over mocks for complex dependencies (repositories, data sources)

§7 Build & Release

Build Variants

debug       → dev API, logging on, no minification, debuggable
staging     → staging API, logging on, minified, not debuggable
release     → prod API, logging off, minified, signed

Gradle Best Practices (Native)

  • build.gradle.kts only — no Groovy DSL in new projects
  • Version catalog (libs.versions.toml) for all dependency versions
  • buildConfig for environment-specific constants
  • Baseline profiles for startup performance
  • R8 full mode enabled in release; maintain proguard rules in version control

CI/CD Pipeline

PR Opened
  └─ lint + unit tests + build debug APK          [< 5 min]

Merge to main
  └─ unit + integration tests + staging build     [< 15 min]
  └─ deploy to Firebase App Distribution (QA)

Release tag
  └─ full test suite + E2E on device farm         [< 45 min]
  └─ build release AAB
  └─ upload to Play Console (internal track)
  └─ promote: internal → closed testing → open → production

Recommended CI: GitHub Actions, Bitrise, or CircleCI.

Play Store Release Strategy

  • Always release to internal → closed → open testing before production
  • Use staged rollouts: 5% → 20% → 50% → 100% with 24-48h monitoring
  • Monitor Crashlytics + ANR rate + rating before expanding rollout
  • Never skip staged rollout for significant changes

App Signing

  • Upload key (Play App Signing): stored in CI secrets, never committed
  • Use Google Play App Signing for distribution key management
  • Document key recovery procedure in team runbook

§8 Performance

Startup Performance

  • App startup time target: cold start < 1s, warm start < 500ms
  • Use App Startup library for initializing libraries lazily
  • Baseline profiles generated + committed to repo
  • Heavy initialization moved off main thread

UI Performance

  • Target: 60fps (90/120fps on supported devices); zero jank
  • Measure with Android Studio Profiler + FrameMetrics API
  • Avoid allocation in draw() / onMeasure() / composition
  • Use derivedStateOf in Compose to avoid unnecessary recompositions
  • Image loading: Coil (Compose) / Glide / Picasso — never load full-res in thumbnails

Memory

  • No Activity / Context references in ViewModels or singletons
  • WeakReferences for listeners stored beyond their owner's lifecycle
  • Bitmap recycling and memory cache sizing
  • Heap dump + leak detection via LeakCanary in debug builds (always)

Network

  • HTTP caching headers respected
  • Image CDN + WebP format
  • Gzip/Brotli compression verified
  • Request batching where applicable
  • Connection pooling configured

Battery

  • Background work only via WorkManager with appropriate constraints
  • Location updates: request only needed accuracy level; stop when backgrounded
  • Wakelocks used sparingly with explicit release

§9 Debugging & Bug Fixing

Debugging Process

  1. Reproduce reliably — document exact steps, device, OS version, account state
  2. Isolate — is it UI, business logic, network, or persistence?
  3. Instrument — add targeted logs / breakpoints, NOT shotgun logging
  4. Hypothesize — form 1-3 specific hypotheses before touching code
  5. Fix the root cause — never patch symptoms; trace back to the source
  6. Regression test — write a test that fails before fix, passes after
  7. Document — comment explaining why the fix works, not just what it does

Common Android Bug Patterns

BugLikely CauseFix
ANRMain thread I/O / long computationMove to coroutine/Dispatcher.IO
Memory leakContext stored in singletonUse applicationContext; WeakRef
Crash on rotationViewModel not used; state not savedrememberSaveable / ViewModel
UI lagRecomposition loopsderivedStateOf, stable params
Blank screen after API callError swallowed silentlyCheck error state propagation
Deep link not workingManifest intent-filter missingVerify adb shell am start test
Push notification silentBackground restrictionsTest on real devices across OEMs

Logging Standards

  • Production: Firebase Crashlytics only (no Log.d in release builds)
  • Debug/Staging: Timber with debug tree
  • Log levels: ERROR (crashes), WARN (recoverable), INFO (key events), DEBUG (dev only)
  • Never log PII — mask emails, phone numbers, tokens in logs

OEM-Specific Issues

  • Test on Samsung, Xiaomi/MIUI, OnePlus/OxygenOS, Huawei (no GMS) for critical flows
  • Background restrictions vary widely by OEM — test push, alarms, background sync
  • Maintain a physical or cloud device farm with top market-share devices

§10 Development Roadmap

Follow this phase structure for any new Android project:

Phase 0 — Foundation (Week 1-2)

  • Stack decision documented with rationale
  • Module structure defined
  • Design system tokens defined (colors, type, spacing, shapes)
  • CI pipeline running (lint + unit tests + build)
  • Crash reporting integrated (Crashlytics/Sentry)
  • Analytics baseline integrated (Firebase/Amplitude)
  • API contract / mock server set up
  • DI framework configured
  • Navigation skeleton implemented
  • Flavor/build variant config complete

Phase 1 — Core Features (Weeks 3-8)

  • Auth flow (login, register, token refresh, logout)
  • Core screen shells with real navigation
  • Network layer (client, interceptors, error handling)
  • Local persistence layer (DB schema + DAOs)
  • Repository layer wiring remote + local
  • ViewModels + UI states for each feature
  • Unit tests for all ViewModels + use cases
  • Feature flags infrastructure

Phase 2 — Polish (Weeks 9-12)

  • Design QA pass against Figma/spec
  • Accessibility audit (TalkBack, contrast, touch targets)
  • Dark mode implementation + verification
  • Localization (strings externalized, RTL support if needed)
  • Loading, empty, error states on every screen
  • Deep link handling
  • Widget / notification implementation
  • Offline mode verification

Phase 3 — Hardening (Weeks 12-14)

  • Performance profiling (startup, scroll, memory)
  • E2E test suite on device farm (Firebase Test Lab)
  • Security review (certificate pinning, biometrics, secure storage)
  • Proguard / R8 rules verified
  • Crash-free rate ≥ 99.5% on staging
  • Play Store listing, screenshots, privacy policy

Phase 4 — Release

  • AAB signed and uploaded to internal track
  • Staged rollout plan defined
  • Monitoring dashboard set up (Crashlytics, Play Console vitals)
  • Rollback plan documented
  • On-call rotation assigned

Phase 5 — Post-Launch (Ongoing)

  • Crash-free rate monitored daily
  • ANR rate < 0.47% (Play Store threshold)
  • App rating monitored; negative reviews triaged weekly
  • Dependency updates reviewed monthly
  • OS beta testing with each new Android release

Limitations

  • This skill is scoped to Android and Android-adjacent delivery paths; it does not cover iOS-only architecture, App Store release operations, or Apple platform UI guidance.
  • Version numbers, Play Console policy thresholds, and recommended libraries can change; verify release-critical details against current Android, Google Play, and library documentation before shipping.
  • Code snippets are architecture patterns, not complete applications; adapt package names, dependency versions, permissions, privacy disclosures, and security controls to the actual project.
  • The guidance does not replace device QA, accessibility review, security review, legal/privacy review, or store compliance checks for a production release.

Additional Resources

For stack-specific deep dives, read:

  • references/native-android.md — Kotlin, Compose, Room, Hilt, Coroutines
  • references/java-android.md — Java, XML Views, ViewBinding, LiveData, Retrofit, Room, Hilt, migration path
  • references/flutter.md — Dart, BLoC/Riverpod, Drift, go_router
  • references/react-native.md — TypeScript, RN architecture, Hermes, New Architecture
  • references/kmm.md — KMM shared modules, SQLDelight, Ktor, Compose Multiplatform
  • references/hybrid.md — Capacitor, Ionic, PWA considerations

Bundled with this artifact

8 files

Reference files that ship alongside this artifact. Agents pull these in only when the task needs them.

More on the bench

SKILL0

Zustand Store Ts

Create Zustand stores following established patterns with proper TypeScript types and middleware.

ai-prompt-engineering+3
0
SKILL0

Zoom Automation

Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio). Always search tools first for current schemas.

ai-prompt-engineering+3
0
SKILL0

Zoho Crm Automation

Automate Zoho CRM tasks via Rube MCP (Composio): create/update records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.

ai-prompt-engineering+3
0