Android dev
Skill sickn33/agentic-awesome-skills/plugins/agentic-awesome-skills-claude/skills/android-dev
AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 1,987+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.
npx -y skills add sickn33/agentic-awesome-skills --skill android-devAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Production-grade Android app development guide covering native (Kotlin/Java), cross-platform (Flutter, RN, KMM), and hybrid architectures.
SKILL.md
21.4 KB, ~5.2k tokens by cl100k_base, as published. Nobody here has run it
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
| 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/SharedFlowfor reactive statesealed class UiState+sealed class UiEvent- Hilt for DI, coroutines + Flow for async
- Repository pattern wrapping Room + Retrofit
Flutter (BLoC or Riverpod):
BlocorCubitfor business logic isolationAsyncNotifierProvider(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
commonMainholds domain + data layers expect/actualfor 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:
- Color tokens — Primary, secondary, surface, on-surface, error; light + dark variants
- Typography scale — Display, headline, title, body, label (Material 3 type system)
- Spacing scale — 4dp grid system (4, 8, 12, 16, 24, 32, 48dp)
- Shape tokens — Corner radii per component family
- Component library — Button, TextField, Card, BottomSheet, TopAppBar, etc.
Jetpack Compose UI Rules
- Use
MaterialThemetokens; never hardcode colors/dimensions CompositionLocalfor theme, locale, hapticsremember/rememberSaveablecorrectly (saveable for UI state surviving rotation)- Extract large composables into sub-composables; each function ≤ 80 lines
- Use
LazyColumn/LazyVerticalGridfor lists; neverColumnwith 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:
contentDescriptionorsemantics { } - Min touch target: 48×48dp
TalkBackcompatibility tested before every release- Dynamic text size support (
spnotdpfor text) - Color contrast ratio ≥ 4.5:1 (WCAG AA)
Navigation
- Native: Navigation Compose with typed
NavHostandSafeArgsequivalent - Flutter:
go_routerwith 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 +
WindowInsetshandling required for Android 15+
Best Practices
Language Standards
Kotlin:
- Prefer
data class,sealed class,object,enum classappropriately - No
!!null assertions — use?.let,?: return,requireNotNullwith message - Coroutines: always specify
CoroutineScope+Dispatcherexplicitly; neverGlobalScope - Use
@Stable/@Immutableon Compose state classes for smart recomposition
Java:
@NonNull/@Nullableannotations on every method param and return type- Never call methods on unchecked objects — null-check explicitly or use
Objects.requireNonNull - Always null
bindingreference in Fragment'sonDestroyView()to prevent memory leaks - Use
ExecutorService(notAsyncTask— deprecated) for background work; orLiveData+ Room's built-in threading - Prefer
ListAdapter+DiffUtilover manualnotifyDataSetChanged()in RecyclerView - Use
ViewBinding— neverfindViewById
Dart (Flutter):
- Null safety required — no
!without explicit null check above - Immutable state objects with
copyWith constconstructors on all stateless widgets
TypeScript (RN):
strict: truein tsconfig always- Zod or io-ts for runtime type validation of API responses
- No
any— useunknownand 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
Activitycontext 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)
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/MMKVas single source of truth- Expose network state via
ConnectivityManagerand 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+mswfor 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.ktsonly — no Groovy DSL in new projects- Version catalog (
libs.versions.toml) for all dependency versions buildConfigfor 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 +
FrameMetricsAPI - Avoid allocation in
draw()/onMeasure()/ composition - Use
derivedStateOfin Compose to avoid unnecessary recompositions - Image loading: Coil (Compose) / Glide / Picasso — never load full-res in thumbnails
Memory
- No
Activity/Contextreferences 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
- Reproduce reliably — document exact steps, device, OS version, account state
- Isolate — is it UI, business logic, network, or persistence?
- Instrument — add targeted logs / breakpoints, NOT shotgun logging
- Hypothesize — form 1-3 specific hypotheses before touching code
- Fix the root cause — never patch symptoms; trace back to the source
- Regression test — write a test that fails before fix, passes after
- 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.din 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, Coroutinesreferences/java-android.md— Java, XML Views, ViewBinding, LiveData, Retrofit, Room, Hilt, migration pathreferences/flutter.md— Dart, BLoC/Riverpod, Drift, go_routerreferences/react-native.md— TypeScript, RN architecture, Hermes, New Architecturereferences/kmm.md— KMM shared modules, SQLDelight, Ktor, Compose Multiplatformreferences/hybrid.md— Capacitor, Ionic, PWA considerations