Skip to content
android-dev ยท agentic-awesome-skills ยท Flowy
Production-grade Android app development guide covering native (Kotlin/Java), cross-platform (Flutter, RN, KMM), and hybrid architectures.
One skill from agentic-awesome-skills .
$ npx -y skills add sickn33/agentic-awesome-skills --skill android-dev --agent claude-codeInstalls just this skill. Get the whole plugin for auto-invocation.
โก How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itself Claude auto-loads it when your prompt matches the work. You can call it Invoke it directly when you want it. Slash command /android-dev๐๏ธ Context preview
The summary Claude sees to decide when to auto-load this skill.
Production-grade Android app development guide covering native (Kotlin/Java), cross-platform (Flutter, RN, KMM), and hybrid architectures. ๐ฆ Ships with agentic-awesome-skills
</> SKILL.md
android-dev.SKILL.md
---
name : android-dev
description : "Production-grade Android app development guide covering native (Kotlin/Java), cross-platform (Flutter, RN, KMM), and hybrid architectures."
risk : safe
source : community
date_added : "2026-06-08"
---
# 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)
Flowy AI Flows that just work. Hand-picked Claude Code plugins that fire the right skill as you prompt.
- 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
| Requirement | Native Kotlin | Native Java | Flutter | RN | KMM | Hybrid |
|---|---|---|---|---|---|---|
| Android-only (new) | โ
Best | โ
| โ
| โ
| โ
| โ
|
| Android-only (existing Java) | โ ๏ธ migrate | โ
Best | โ | โ | โ ๏ธ | โ |
| Android + Web | โ | โ | โ
| โ
| โ
| โ
Best |
| Android + Desktop | โ | โ | โ
| โ ๏ธ | โ
| โ ๏ธ |
| Shared business logic only | N/A | N/A | N/A | N/A | โ
Best | N/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
| Type | Strategy |
|------|----------|
| Network errors | Retry with exponential backoff; show retry UI |
| Auth errors (401/403) | Refresh token โ re-request โ logout if fails |
| Validation errors | Show inline field errors immediately |
| Data parsing errors | Log + fallback to cached/default state |
| Unexpected crashes | Catch at top-level; show error screen + report |
| Background task failures | Retry via WorkManager; notify user if critical |
### Result / Either Pattern (Kotlin)
```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
| Bug | Likely Cause | Fix |
|-----|-------------|-----|
| ANR | Main thread I/O / long computation | Move to coroutine/Dispatcher.IO |
| Memory leak | Context stored in singleton | Use `applicationContext`; WeakRef |
| Crash on rotation | ViewModel not used; state not saved | `rememberSaveable` / ViewModel |
| UI lag | Recomposition loops | `derivedStateOf`, stable params |
| Blank screen after API call | Error swallowed silently | Check error state propagation |
| Deep link not working | Manifest intent-filter missing | Verify `adb shell am start` test |
| Push notification silent | Background restrictions | Test 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
ยฉ 2026 Flowy ยท Free and open source
Built for Claude Code ยท Not affiliated with Anthropic