Application architecture
A layered structure with clear boundaries between presentation, domain and data, so features can be added without the codebase becoming a single mutable state.
- Kotlin and Java, Android SDK, Jetpack components
- Lifecycle-aware components and state handling
- Dependency boundaries and module structure
- UI/UX implementation against agreed designs
Data & persistence
Local storage designed for the case where the network is unavailable, slow or lying, rather than for the case where it works.
- Room database schema, migrations and queries
- Offline-capable read and write paths
- Sync, conflict handling and idempotent writes
- Caching strategy and eviction
Background execution
The area where Android differs most across manufacturers and versions, and where most reliability complaints originate.
- WorkManager for deferrable and constrained work
- Foreground services with correct types and notifications
- Background service behaviour across API levels
- Boot, alarm and connectivity-triggered work
Integrations
The application's contract with everything outside it, designed so that a failure on one side degrades rather than crashes.
- REST API integration, authentication and token refresh
- Firebase Cloud Messaging and push notification handling
- Deep links and app links
- Timeout, retry and backoff behaviour
Instrumentation & quality
Enough visibility to answer what happened on a device we do not have in front of us.
- Firebase Analytics event schema and conversion events
- Crash and ANR monitoring, with triage
- Firebase Remote Config for controlled rollout of behaviour
- Startup, memory, jank and battery profiling
Monetisation
In-app advertising integrated so that revenue can be compared against acquisition cost on consistent definitions.
- AdMob integration and ad format placement
- Mediation via TradPlus or TopOn where used
- Ad revenue event reporting into analytics
- Consent and policy-relevant configuration