Skip to content
Engineering deep-divesAll articles

How to Build an Android App: Kotlin, Compose & Play Store

An engineering guide to native Android app development in 2026: how we build production apps with Kotlin 2.x, Jetpack Compose, and Room while taming hardware fragmentation, OEM background task killers, Baseline Profiles, and Google Play Vitals gates.

Oleksandr Saiko
Oleksandr SaikoCEO · Idealogic
Author: Oleksandr SaikoPublished: Updated: Reading time: 18 minHow we write →
On this page
Idealogic: Android app development stack and process

Understanding how to build an Android app in 2026 starts with recognizing what makes Google's ecosystem fundamentally different from every other computing platform: unmatched global scale paired with extreme hardware diversity. When you ship an Android application, your binary does not run on a single vendor's controlled product line. It runs on a $110 Motorola handset in São Paulo, a Samsung Galaxy Z Fold in Seoul, a rugged Zebra barcode terminal inside a German warehouse, and a Pixel flagship in New York. Writing in Kotlin and Jetpack Compose is the straightforward part; engineering your architecture to survive that hardware spread is where real Android craftsmanship lives.

At Idealogic, we architect and ship native Android applications for consumer brands, fintech platforms, healthcare providers, and logistics fleets. If you want an experienced engineering team to build and launch your product end to end, visit our Android app development services page. If you want the complete technical blueprint before writing code, this guide covers the 2026 Kotlin 2.x and Jetpack Compose stack, multi-module Gradle builds, engineering defenses against device and OEM fragmentation, StrongBox and Play Integrity security, Google Play Vitals gates, and realistic 2026 build costs.

The short version

  • Kotlin 2.x (K2 compiler) and Jetpack Compose define the 2026 stack: declarative Material Design 3 UI paired with Coroutines, StateFlow, Room SQLite, DataStore, and Hilt dependency injection replaces legacy Java and XML Fragments across new builds.
  • Device and OEM fragmentation is solved by architecture, not luck: Material 3 WindowSizeClass adaptive layouts handle phones, foldables, and tablets, while WorkManager and foreground service types prevent Samsung and Xiaomi battery savers from silently killing background sync.
  • Baseline Profiles and R8 full mode are mandatory for mid-range speed: bundling ahead-of-time ART compilation profiles and full R8 bytecode shrinking cuts cold-start times and scroll jank by 30% to 40% on budget hardware.
  • Hardware security relies on StrongBox and the Play Integrity API: storing non-exportable keys in the Android Keystore StrongBox chip and verifying client attestation via Google Play Integrity blocks rooted device tampering and repackaged APKs.
  • Google Play Vitals govern store visibility: staged rollouts must keep user-perceived crash rates below 1.09% and Application Not Responding (ANR) rates under 0.47%, or Google Play demotes your organic search ranking.
  • A production native Android v1 takes 10 to 18 weeks and $30k to $95k: budget scales with workflow complexity, offline sync requirements, compliance scope, and the breadth of your physical device QA matrix.

Why native Android app development is its own engineering discipline

According to StatCounter GlobalStats mobile OS data, Android powers 70% to 72% of smartphones worldwide, dominating continental Europe, Latin America, India, Southeast Asia, Africa, and enterprise hardware. Even in North America and Northern Europe where iOS leads consumer share, no mass-market product, field-operations platform, or regulated service can ignore Android without leaving millions of users behind.

Yet the costliest mistake we see in rescue audits is treating an Android build as a line-by-line port of an iPhone spec. Android runs on a fundamentally different runtime and OS contract:

  • The Android Runtime (ART) and garbage collection: Unlike Swift's deterministic ARC, Android executes bytecode on ART using generational garbage collection paired with ahead-of-time (AOT), profile-guided, and just-in-time (JIT) compilation. Allocating objects inside a 120Hz Compose draw pass triggers GC pauses and dropped frames on 4 GB RAM phones unless state stability is engineered deliberately.
  • Configuration changes and process death: Rotating a screen, unfolding a hinged display, or toggling dark mode destroys and recreates the host Activity by default. When a user switches to a heavy camera app, the OS silently kills backgrounded processes to reclaim RAM, expecting your app to restore navigation and form state seamlessly via SavedStateHandle.
  • Vendor-modified Android ROMs: Samsung One UI, Xiaomi HyperOS, Oppo ColorOS, and Vivo FuntouchOS modify AOSP background scheduling, notification channels, and camera HALs in ways an emulator never reproduces.

Native Android vs cross-platform in 2026: when to write pure Kotlin

We analyze the financial and technical trade-offs between native and cross-platform stacks in native vs cross-platform app development and our cross-platform vs native knowledge base reference. Here is how we evaluate the choice for Android:

FactorNative Android (Kotlin 2.x + Compose)Cross-Platform (React Native)Cross-Platform (Flutter)
Runtime & CompilerKotlin 2.x compiled to DEX; AOT/JIT compiled by ART with R8 shrinkingTypeScript on Hermes engine with synchronous JSI C++ bindingsDart compiled AOT to ARM64 with Impeller Vulkan/OpenGL engine
Hardware & OS AccessDirect access to Foreground Services, WorkManager, NFC/HCE, BLE, USB, CameraX, NDKRequires custom TurboModules in Kotlin or community bridgesRequires MethodChannel / FFI bridges for background and hardware APIs
Budget Phone SpeedSmallest binary and lowest RAM overhead; Baseline Profiles speed up cold startHermes + JS bundle adds ~10-18 MB and extra RAM pressure on 3-4 GB phonesImpeller engine adds ~12-22 MB; smooth rendering but higher baseline RAM
Cost (Android + iOS)100% baseline when paired with a separate native iOS build60% to 65% of dual-native cost; shares 75% to 90% of TypeScript code60% to 65% of dual-native cost; shares widget tree and business logic
Ideal Product FitAndroid-first markets, hardware/IoT/BLE, background utilities, enterprise fleet/kioskConsumer and B2B SaaS products launching on Android and iOS simultaneouslyBrand-driven custom UIs, multi-platform apps needing identical visuals

If your business needs both Android and iOS in the same quarter and centers on standard API-driven screens, compare React Native vs Flutter first. When Android is your primary market, when your app must fly on budget hardware, or when your core value depends on background services, BLE, NFC, or enterprise device management, native Kotlin wins.

The 2026 native Android technology stack

Google has consolidated Android engineering around Modern Android Development (MAD), replacing verbose Java boilerplate, brittle AsyncTask threads, and fragile Fragment lifecycles. Here is the production stack we standardize on at Idealogic in 2026:

Layer2026 Production StandardLegacy / Secondary OptionProduction Rationale
LanguageKotlin 2.x (K2 Compiler) + Coroutines + FlowJava / RxJava (maintenance only)Null safety, structured concurrency, 2x faster K2 builds, lightweight suspension
UI & DesignJetpack Compose + Material Design 3XML View system + RecyclerViewDeclarative Kotlin UI, adaptive WindowSizeClass layouts, zero XML inflation
State & UDFUnidirectional Data Flow + ViewModel + StateFlowMVP / Imperative LiveDataImmutable UI states and lifecycle-aware collectAsStateWithLifecycle()
DIHilt (Dagger on KSP) or KoinService locators / Dagger 2 KAPTCompile-time graph validation scoped to Activity, ViewModel, and WorkManager
PersistenceRoom SQLite (with KSP) + Jetpack DataStoreSQLiteOpenHelper + SharedPreferencesCompile-time SQL checks, reactive Flow queries, transactional Proto storage
NetworkingRetrofit / OkHttp (or Ktor) + Kotlinx Serialization + WorkManagerVolley / Gson (reflection)Code-generated parsers, HTTP/3 pooling, guaranteed background task execution
Build & PerfGradle (Kotlin DSL + Convention Plugins) + R8 Full Mode + Baseline ProfilesGroovy Gradle + KAPTModular cached builds, 30%+ smaller binaries, pre-compiled startup paths
Five layers of native Android engineering: Jetpack Compose and Kotlin on top, compiled through Gradle into a Google Play App Bundle engineered to survive hardware diversity at the bottom.

Kotlin 2.x (K2 compiler), Coroutines, and StateFlow architecture

As detailed in our Kotlin knowledge base guide and the Kotlin documentation, the Kotlin 2.x K2 compiler rewrote the frontend semantic pipeline, nearly doubling incremental build speeds and improving smart-cast inference across sealed interfaces.

Following the Android Developers Guide to App Architecture, we structure every screen around Unidirectional Data Flow (UDF) with Coroutines and StateFlow:

  1. Immutable UI State (sealed interface or data class): Each ViewModel exposes one val uiState: StateFlow<ScreenUiState> (Loading, Success, Empty, Error). User intents flow up to the ViewModel; immutable state flows down to Compose.
  2. Lifecycle-aware collection (collectAsStateWithLifecycle): Collecting flows with plain collectAsState() keeps database queries, location listeners, and polling active when the app is backgrounded. Using collectAsStateWithLifecycle() pauses collection when the lifecycle drops below Lifecycle.State.STARTED, saving battery and preventing background crashes.
  3. Offline-first synchronization: Repositories write API payloads into Room SQLite tables first and expose a reactive Flow<List<DomainModel>> to the UI. Screens render cached local data in under 50ms on cold start while network refresh runs asynchronously.

Jetpack Compose performance: avoiding recomposition jank

Jetpack Compose eliminates XML layout files, but smooth 60Hz and 120Hz rendering requires strict state stability so the Compose compiler skips unchanged subtrees:

  • Enforce immutable models: Annotate cross-module models with @Immutable or @Stable, or use ImmutableList<T> so Compose knows list properties cannot mutate unseen.
  • Defer state reads with lambda modifiers: Pass rapidly changing scroll or drag values via lambda modifiers like Modifier.offset { IntOffset(x, scrollOffset) } or Modifier.graphicsLayer { alpha = animatedAlpha } to skip Composition and run directly in Layout or Draw.
  • Supply stable key lambdas in LazyColumn: Always pass key = { item -> item.id } so row insertions or deletions do not force full item rebinding on mid-range phones.

Multi-module Gradle builds, KSP, and convention plugins

Monolithic :app modules using legacy kapt (Kotlin Annotation Processing Tool) stall engineering velocity because kapt generates Java stubs on every build. In our mobile app architecture blueprint, we enforce two rules from Sprint 1:

  1. Migrate 100% of processors to KSP (Kotlin Symbol Processing): Room and Hilt run directly on Kotlin symbols via KSP, cutting annotation processing time in half.
  2. Partition with Gradle Convention Plugins and Version Catalogs (libs.versions.toml): We split repositories into :app, :core:designsystem, :core:network, :core:database, :core:model, and isolated :feature:* modules governed by Kotlin DSL convention plugins in build-logic/. Editing :feature:checkout recompiles only that module while pulling unchanged siblings from the Gradle build cache.

Conquering Android device, screen, and OEM fragmentation

Fragmentation is the price of Android's global reach. Your binary runs across dozens of aspect ratios, multiple OS versions, budget chipsets, and aggressive OEM firmwares.

Four architectural defenses turn Android hardware diversity from a launch-week crisis into a predictable engineering checklist.

Here is the engineering matrix we use to tame the five vectors of Android fragmentation:

Fragmentation VectorReal-World Failure Mode2026 Engineering Defense
1. OS Version Spread (API 26 to 35+)Calling newer APIs crashes older phones with NoSuchMethodError; Google Play blocks outdated target SDKsSet minSdk = 26 (or 28) for 96%+ coverage; set targetSdk = 35+; use AndroidX Jetpack compat wrappers
2. Foldables, Tablets & Aspect RatiosPhone layouts stretch on tablets or lose state when a Galaxy Z Fold unfoldsBuild with Material 3 WindowSizeClass (Compact, Medium, Expanded), ListDetailPaneScaffold, and enableEdgeToEdge()
3. Budget CPU & Storage BottlenecksFirst launch and initial scroll stutter for 2 to 4 seconds during JIT compilation on $150 phonesEnable R8 full mode (android.enableR8.fullMode=true) and ship Baseline Profiles + Startup Profiles
4. OEM Background Task KillersSamsung One UI, Xiaomi HyperOS, and OnePlus battery savers kill background sync threadsRoute deferrable jobs through Jetpack WorkManager (setExpedited), declare Android 14+ foreground service types, and wake via FCM
5. Camera & Sensor VarianceRaw Camera2 code produces rotated previews or crashes on specific Samsung or Xiaomi sensorsStandardize on Jetpack CameraX, tested by Google across hundreds of physical OEM camera modules

Adaptive layouts with Material Design 3 and WindowSizeClass

In Google's Material Design 3 (M3) guidelines and Android 15+, our UI/UX design and Android teams apply two layout rules to every mobile app design:

  • Mandatory edge-to-edge insets: Apps targeting Android 15 (API 35) draw edge-to-edge behind system bars by default. Screens must consume WindowInsets (Scaffold innerPadding, Modifier.systemBarsPadding(), Modifier.imePadding()) so primary buttons never hide behind navigation bars or the keyboard.
  • Responsive WindowSizeClass breakpoints: Reading currentWindowAdaptiveInfo().windowSizeClass lets a screen render a bottom NavigationBar on Compact phones and automatically switch to a side NavigationRail and two-pane ListDetailPaneScaffold on Medium foldables and Expanded tablets without losing state.

Baseline Profiles and R8 full mode: 30%+ faster cold starts

Unlike iOS binaries that arrive pre-compiled to ARM64 machine code, Android apps ship as DEX bytecode compiled on the handset by ART. Without profile rules, budget phones rely on JIT interpretation during the first session, causing slow cold starts and onboarding jank.

We eliminate that penalty using Android Baseline Profiles (androidx.profileinstaller + Macrobenchmark), Startup Profiles, and R8 full mode:

  1. Ahead-of-time compilation via Baseline Profiles: Automated instrumentation tests launch the app and exercise primary scroll and checkout paths to generate baseline-prof.txt inside the App Bundle. Google Play uses those rules alongside Cloud Profiles to ahead-of-time compile critical methods during installation, cutting cold start times and first-scroll frame jank by 30% to 40%.
  2. DEX layout optimization via Startup Profiles: Pairing Baseline Profiles with a Startup Profile instructs R8 to pack all classes needed before the first frame (reportFullyDrawn()) into the primary classes.dex file, minimizing flash storage page faults on older eMMC and UFS chips.
  3. R8 full-mode shrinking: Enabling android.enableR8.fullMode=true strips unused library code, inlines short Kotlin functions, optimizes sealed classes, and shrinks resource tables, reducing download size by 25% to 45%.

Hardware security, Play Integrity API, and OWASP MASVS compliance

Because Android permits APK sideloading, adb debugging, and bootloader unlocking, client security demands hardware key storage and runtime attestation. For fintech, healthtech, and enterprise products, we build against the OWASP Mobile Application Security Verification Standard (MASVS v2.1), detailed in our mobile app security guide:

  • Android Keystore and StrongBox: Never store tokens in plaintext SharedPreferences. We generate AES-256-GCM keys inside the Android Keystore backed by a hardware StrongBox chip (setIsStrongBoxBacked(true)) with TEE fallback, storing encrypted payloads in Jetpack DataStore.
  • BiometricPrompt (Class 3) and CredentialManager: We bind BiometricPrompt.CryptoObject to Keystore cipher unlocking (setUserAuthenticationRequired(true)) so biometric checks are enforced by the OS kernel, and use Jetpack CredentialManager for Passkeys and Google Sign-In.
  • Google Play Integrity API: Before executing sensitive mutations, our backend verifies signed Play Integrity attestation tokens across three verdicts:
    1. Device integrity (MEETS_STRONG_INTEGRITY / MEETS_DEVICE_INTEGRITY): Confirms genuine, unrooted Android hardware rather than an emulator or hooked ROM.
    2. Application integrity (PLAY_RECOGNIZED): Confirms the binary signature matches Google Play's unmodified release rather than a repackaged APK.
    3. Account licensing (LICENSED): Confirms legitimate Play Store installation.
  • Network Security Config: Disables cleartext HTTP (cleartextTrafficPermitted="false") and pins SHA-256 SPKI public keys with backup pins inside network_security_config.xml.
On Android, open distribution means your backend can never trust a client request on faith. Pairing StrongBox hardware keys with Google Play Integrity attestation ensures your API only talks to an unmodified binary running on unrooted silicon.

Google Play Console release tracks, testing mandates, and Android Vitals

Shipping to Google Play requires a one-time $25 Play Console fee, a signed Android App Bundle (.aab), and passing Google's automated scanners, policy checks, and Android Vitals thresholds.

Every production Android release progresses through signed AAB packaging, closed track validation, automated Firebase Test Lab crawls, and a staged rollout gated by Android Vitals thresholds.

1. Android App Bundles (.aab) and Play Console testing tracks

Using Play App Signing, your CI pipeline signs the .aab with a rotatable Upload Key while Google Play holds the final App Signing Key in cloud HSMs and serves split APKs tailored to each device's CPU architecture (arm64-v8a), screen density, and language, trimming install size by 15% to 30%. Always bundle your R8 mapping.txt file and native debug symbols for readable crash traces.

Builds progress through three pre-production gates:

  • Internal Testing Track: Deploys builds to up to 100 internal testers in under 60 seconds to test Play Billing and Play Integrity in Sprint 1.
  • Closed Testing Track (and the 14-day personal account rule): Google requires newly created personal Play accounts to run a closed test with 12 to 20 opted-in testers continuously for 14 days before unlocking Production access. Businesses should always register a Google Play Organization account with a verified D-U-N-S number in Week 1 to avoid this bottleneck.
  • Firebase Test Lab Pre-launch Reports: Every testing upload triggers an automated Robo crawl across physical handsets in Firebase Test Lab, surfacing crash videos, layout overlaps, and accessibility warnings automatically.

2. Google Play policy reviews and Android Vitals thresholds

To clear review on try one and protect store search rankings, engineer around four Google Play gates:

  1. Granular permissions (Photo Picker and ACCESS_BACKGROUND_LOCATION): Use the system Android Photo Picker (PickVisualMedia) instead of broad READ_MEDIA_IMAGES permissions, and avoid background location unless justified by a dedicated video review declaration.
  2. Data Safety & web account deletion: Disclose all SDK data collection accurately in the Data Safety form, and provide both an in-app Delete Account flow and a public web deletion URL.
  3. Google Play Billing Library v7+: Route digital subscriptions and in-app purchases through Play Billing verified via Real-time Developer Notifications (RTDN).
  4. Android Vitals bad-behavior thresholds: Google Play demotes organic search visibility if your rolling 28-day metrics breach 1.09% user-perceived crash rate or 0.47% user-perceived ANR rate (main thread blocked > 5 seconds). We roll out from 5% to 100% in stages only while crash-free sessions hold above 99.5% and ANRs stay below 0.15%.

2026 Android app development timelines and cost breakdown

We publish a full cross-platform and native financial breakdown in our mobile app development cost guide and walk through all seven delivery phases in how to build a mobile app. Below are realistic 2026 timelines and budgets for a native Kotlin and Jetpack Compose build with a senior Eastern European squad (US agencies typically bill 1.8x to 2.2x higher):

Project TierTypical Scope & Native Android CapabilitiesSquad SizeTimeline2026 Budget (Senior CEE Squad)
1. Focused Native Android MVPOne core workflow (5-8 screens), Compose M3 UI, OAuth/Passkeys, API integration, FCM notifications, Play Store launch1 Designer, 1-2 Android Eng, 1 Backend Eng, 0.5 QA8 to 12 weeks$30,000 to $50,000
2. Production Consumer / B2B v1Full product (12-20 screens), multi-module Kotlin 2.x + Room offline sync, Google Pay or Play Billing, foldable layouts, Baseline Profiles, CI/CD1 PM, 1 Designer, 2 Android Eng, 1-2 Backend Eng, 1 QA12 to 16 weeks$55,000 to $95,000
3. Regulated Fintech / HealthtechStrongBox Keystore, Play Integrity attestation, OWASP MASVS L2, BLE medical sensors or NFC/HCE payments, KYC/AML, HIPAA/PCI compliance1 PM, 1 Designer, 2-3 Android Eng, 2 Backend Eng, 1 Sec/QA16 to 24 weeks$95,000 to $170,000+
4. Hardware, IoT, or Enterprise KioskAndroid Enterprise MDM / LockTask kiosk mode, rugged barcode/RFID SDKs, USB/Serial/BLE protocols, offline field sync, NDK/C++ pipelinesSpecialized Android Systems & Embedded Engineers + Core Squad16 to 28 weeks$105,000 to $210,000+

During our idea-to-product discovery sprints, we keep Android budgets predictable through three levers:

  1. Lock your device and OS matrix before Sprint 1: Supporting minSdk 26 with standard Compose M3 components moves fast; custom camera shaders on six-year-old 2 GB RAM devices doubles QA time.
  2. Use Material Design 3 adaptive primitives in v1: Building on M3 tokens, NavigationSuiteScaffold, and system sheets gives you foldable, tablet, dark-mode, and TalkBack support automatically.
  3. Evaluate shared vs dual-native early: If you need Android and iOS simultaneously without specialized hardware dependencies, check our mobile app development hub and mobile app development knowledge base to see if a shared codebase fits better. If you are building native apps for both stores, pair this guide with our playbook on how to build an iOS app.
Planning a native Android app in Kotlin and Jetpack Compose? Get an architecture plan and build estimate
Talk to our Android engineering team

Occasional field notes on building software, no spam

Protected by Cloudflare Turnstile · Privacy · Terms

Oleksandr Saiko
Oleksandr SaikoCEO · Idealogic Development OÜ

CEO and Co-founder at Idealogic. Leading software strategy, systems architecture, and AI-native engineering squads since 2016.

Frequently asked questions

  • Android app development is the engineering discipline of building native software for Android phones, foldables, tablets, and enterprise hardware using Kotlin 2.x, Jetpack Compose, and Android Studio. A production 2026 build combines unidirectional StateFlow state management, Room SQLite persistence, Baseline Profiles for ahead-of-time startup optimization, and signed Android App Bundles shipped through Google Play.

  • Build every new Android application in Jetpack Compose paired with Material Design 3. Google develops all modern UI primitives, adaptive foldable layouts, and animation APIs Compose-first, while the legacy XML View and Fragment system is in maintenance mode. Compose reduces UI boilerplate by 40% to 50% and interoperates with existing XML views via ComposeView and AndroidView when needed.

  • We control fragmentation through four engineering defenses: setting minSdk 26 or 28 to cover over 96% of active devices with modern security patches, building responsive layouts with Material 3 WindowSizeClass breakpoints, using WorkManager to survive aggressive Samsung and Xiaomi background battery killers, and testing on a physical handset matrix that includes budget three-year-old devices.

  • Baseline Profiles are ahead-of-time (AOT) compilation rules bundled inside your Android App Bundle that tell the Android Runtime (ART) which critical startup and scroll paths to pre-compile during installation from Google Play. Paired with R8 full-mode shrinking and obfuscation, Baseline Profiles reduce cold start times and first-scroll frame jank by 30% to 40% on mid-range hardware.

  • Google Play requires newly created personal developer accounts to run a continuous 14-day closed test with at least 12 to 20 opted-in testers before unlocking production store access. To avoid launch delays, businesses should register a Google Play Console Organization account using a verified D-U-N-S number during Week 1 of discovery rather than using a personal Gmail account.

  • A focused native Android MVP with one core workflow and standard API integrations costs $30,000 to $50,000 with a senior Eastern European engineering squad, or $60,000 to $100,000 with a US agency. Full production v1 apps with offline Room sync, Google Pay, adaptive foldable layouts, and Baseline Profiles range from $55,000 to $95,000, while regulated fintech and healthtech builds start at $95,000 to $170,000.

  • A disciplined native Android v1 reaches Google Play in 10 to 18 weeks: 2 weeks for discovery and device-matrix scoping, 3 weeks for Material 3 adaptive UX design, 6 to 8 weeks for modular Kotlin and Jetpack Compose sprints, 2 to 3 weeks for physical handset QA and security hardening, and 1 to 2 weeks for Play Console review and staged rollout.

  • Choose native Kotlin and Jetpack Compose when your product targets Android exclusively, relies on background services, Bluetooth Low Energy, NFC, custom camera/NDK pipelines, or enterprise MDM/kiosk hardware, or must run smoothly on sub-$150 emerging-market phones. If you need both Android and iOS simultaneously for standard data workflows, React Native or Flutter cuts total cost by 30% to 40%.

Still unanswered
Ask us directly

A senior engineer replies under 4 hours.

Related expertise