Building On-Device AI Apps on Android: AICore Implementation & Practical Architecture

Mobile application architecture has reached a major inflection point. For the past three years, integrating artificial intelligence into mobile applications meant wiring UI elements to cloud-hosted API endpoints. While cloud models provide massive parameter scale, they introduce severe liabilities for mobile user experiences: unpredictable network latency, vulnerability to complete failure in offline environments, privacy compliance obstacles when handling sensitive user data, and recurring API token expenses that scale linearly with user engagement.

In 2026, mobile users expect instant, private, and contextual intelligence. Waiting three seconds over a cellular connection for a remote model to summarize a document, rewrite a message, or suggest a calendar reply is no longer acceptable. The maturation of modern mobile silicon—featuring dedicated Neural Processing Units (NPUs) featuring dedicated AI accelerators whose published throughput varies substantially by chipset architecture and vendor measurement standards—has made on-device inference practical for mainstream production applications.

💻 Get the full code on GitHub: runnable source, requirements and setup steps for this tutorial.

Sources & Official Documentation

  • Android Developers AICore Documentation: developer.android.com/ai/aicore — System architecture, supported APIs, and device compatibility.
  • Google AI Edge Developer Guide: ai.google.dev/edge — On-device SDKs, LiteRT, and MediaPipe GenAI runtimes.
  • Android Thermal Management APIs: PowerManager API Reference — Monitoring system thermal mitigation events.
  • Test Environment & Versions: Evaluated on Google Pixel 9 Pro (Android 15) using com.google.ai.edge.aicore:aicore:1.0.0-alpha02 and Jetpack Compose BOM 2024+.

📱 Developer Notice: API Evolution & Device Compatibility

API Status & Hardware Support: Android AICore and Google AI Edge on-device APIs are evolving developer preview technologies. As documented in Android Developers AICore Documentation, access to Gemini Nano requires compatible hardware (currently flagship devices such as Google Pixel 8/9 series and select Samsung Galaxy S-series devices) and system-level AICore service updates distributed via Google Play system updates.

Production Architecture Guidance: In production applications, never assume universal AICore availability across all user devices. Always wrap inference calls in feature-availability checks (e.g., AICore.isAvailable()) and implement a graceful fallback layer—such as MediaPipe GenAI / LiteRT for broader on-device hardware support or a secure cloud endpoint when physical NPU support is absent.

Google’s Android AICore system service and emerging frameworks like PyTorch ExecuTorch enable Android developers to run optimized Small Language Models (SLMs), such as Gemini Nano and quantized Llama 3.2 models, directly on physical hardware. This engineering guide breaks down the underlying system architecture, demonstrates a production-grade Kotlin implementation using Jetpack Compose, and details essential strategies for memory budgeting and thermal management.

The On-Device Advantage: Privacy, Latency, and Cost Predictability

Transitioning intelligence from remote cloud clusters to local mobile devices shifts three foundational engineering constraints:

  1. Zero Network Latency & Offline Independence: Cloud API calls depend on variable cellular signal strength, TLS handshakes, and remote queuing. In contrast, local inference bypasses network round-trips entirely. On-device models deliver Time-To-First-Token (TTFT) metrics under 50 milliseconds, functioning reliably in airplane mode, subway commutes, and areas with spotty connectivity.
  2. Deterministic Data Privacy by Design: In healthcare, enterprise communications, personal finance, and on-device search, transmitting user text and documents across external networks creates significant regulatory and security risks. On-device processing can reduce the volume of sensitive user telemetry transmitted across external networks. However, statutory compliance with privacy regulations (such as GDPR or HIPAA) still depends on the overall application architecture, data retention policies, authentication boundaries, and local encryption controls, and corporate data sovereignty requirements out of the box.
  3. Zero Marginal Inference Cost: Cloud APIs bill developers per input and output token. A high-engagement consumer application can quickly accumulate tens of thousands of dollars in monthly cloud provider bills. On-device execution offloads computation to the end-user’s local processor, enabling unlimited conversational interactions at zero marginal server cost.

However, on-device mobile AI introduces strict hardware boundaries. Unlike cloud servers equipped with 80GB of HBM3 memory, smartphone applications must operate within strict RAM limits, share memory with the Android system, and prevent excessive battery draw or device overheating.

System Architecture: The Android AICore Stack

Android addresses the memory overhead of on-device models through Android AICore, a foundational system-level service introduced in Android 14 and expanded in modern Android releases.

┌────────────────────────────────────────────────────────────────────────┐
│               ANDROID ON-DEVICE AI SYSTEM ARCHITECTURE                 │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  [ Client Application (Jetpack Compose UI / ViewModels) ]              │
│                           │                                            │
│                           ▼ (IPC via AndroidX / Google Play Services)  │
│  [ Android AICore System Service (Background Daemon) ]                 │
│    ├─ Model Lifecycle & Version Management (Gemini Nano OTA Updates)   │
│    ├─ Dynamic LoRA Adapter Ingestion & Multi-Tenant Routing            │
│    └─ System Memory Watchdog (Protects Apps from Low Memory Killer)    │
│                           │                                            │
│                           ▼ (Android NNAPI / Custom Acceleration HAL)  │
│  [ Hardware Abstraction Layer & Vendor Acceleration Runtimes ]         │
│    ├─ Qualcomm QNN / Hexagon Direct Tensor Execution                   │
│    ├─ Google Tensor TPU Driver & Context Scheduler                     │
│    └─ MediaTek NeuroPilot NPU Acceleration Runtime                     │
│                           │                                            │
│                           ▼ (Physical Silicon Execution)               │
│  [ Mobile Hardware: NPU Accelerator Cores & Shared LPDDR5X RAM ]       │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

Why a System Service Architecture Matters

In early mobile AI experiments, developers bundled full model weights inside their APK files. This approach failed for production deployments: an app containing an INT4 2-billion-parameter model bloated download sizes by 1.2GB to 1.8GB, and if three different apps ran local models simultaneously, the smartphone quickly ran out of physical RAM.

Android AICore solves this by treating foundation models as shared system infrastructure:

  • Shared Model Storage: The system manages and updates the base Gemini Nano weights via Google Play system updates. Apps do not bundle gigabytes of model weights inside their APKs.
  • Shared Memory Footprint: The base model weights are memory-mapped into shared system memory once, allowing multiple applications to access the same foundational weights through fine-tuned LoRA (Low-Rank Adaptation) adapters.
  • Safety and Guardrails: Hardware-accelerated safety filters operate directly inside the system service, ensuring content safety without requiring developers to build custom moderation layers.
Android Developers documentation page Gemini Nano, explaining that Gemini Nano runs in Android's AICore system service
Android's official Gemini Nano page: the model runs on the device through the AICore system service.

Framework Evaluation: AICore vs. ExecuTorch vs. ONNX Runtime Mobile

Selecting the appropriate runtime depends on your target device demographic, cross-platform needs, and custom model architectures:

Evaluation VectorAndroid AICore (Google)PyTorch ExecuTorch (Meta)ONNX Runtime Mobile (Microsoft)
Primary Model EcosystemGemini Nano & Google-verified modelsOpen-source PyTorch (Llama, Mistral)Broad cross-framework ONNX exports
APK Binary Footprint ImpactMinimal (~150KB client library)Moderate (4MB–12MB native engine)Moderate (8MB–15MB runtime binary)
Hardware AccelerationSystem-tuned NPU integrationVendor delegates (QNN, CoreML, Vulkan)Execution Providers (NNAPI, QNN, DirectML)
Model Weight DistributionDistributed via Play System UpdatesMust be bundled or downloaded in-appMust be bundled or downloaded in-app
Cross-Platform SupportAndroid only (Google Play devices)Cross-platform (Android, iOS, Embedded)Cross-platform (Android, iOS, Desktop)
Fine-Tuning & AdaptersLoRA adapters managed via AICoreCustom PyTorch weights & quantizationsStatic quantized ONNX graphs
Offline Availability100% offline once device model installs100% offline immediately100% offline immediately

Hands-On Implementation: Building a Local AI Feature in Kotlin

The following production-ready example demonstrates how to integrate on-device generative AI into an Android application using Kotlin, Coroutines, and the Google AI Edge SDK.

Step 1: Add Gradle Dependencies

Add the official Google AI Edge and AndroidX lifecycle libraries to your module’s build.gradle.kts:

GRADLE / KOTLIN — build.gradle.kts
dependencies {
    // Google AI Edge SDK for on-device inference
    implementation("com.google.ai.edge.aicore:aicore:1.0.0-alpha02")
    
    // Jetpack Lifecycle and Coroutines
    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1")
    
    // Jetpack Compose BOM
    implementation(platform("androidx.compose:compose-bom:2026.02.00"))
    implementation("androidx.compose.material3:material3")
}

Step 2: Implement the On-Device Inference Repository

Create a dedicated repository class that checks hardware capability, handles download status, and exposes streaming token generation:

KOTLIN — OnDeviceAiRepository.kt
package com.ismartanji.mobileai.data

import android.content.Context
import com.google.ai.edge.aicore.GenerativeModel
import com.google.ai.edge.aicore.GenerationConfig
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class OnDeviceAiRepository(private val context: Context) {

    private var generativeModel: GenerativeModel? = null

    suspend fun initializeModel(): Result<Unit> = withContext(Dispatchers.IO) {
        try {
            // Configure generation parameters optimized for mobile battery and latency
            val config = GenerationConfig.builder()
                .setTemperature(0.2f) // Lower temperature for factual, deterministic output
                .setTopK(16)
                .setMaxOutputTokens(256)
                .build()

            // Initialize connection to the shared system Gemini Nano service
            generativeModel = GenerativeModel(
                context = context,
                generationConfig = config
            )
            Result.success(Unit)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    fun generateStreamingResponse(prompt: String): Flow<String> = flow {
        val model = generativeModel 
            ?: throw IllegalStateException("Model has not been initialized yet.")

        // Stream tokens asynchronously as they are emitted from the local NPU
        val responseStream = model.generateContentStream(prompt)
        for (chunk in responseStream) {
            chunk.text?.let { emit(it) }
        }
    }
}

Step 3: Connect to Jetpack Compose UI via ViewModel

Implement a reactive ViewModel managing lifecycle-aware UI state and handling on-device token streams:

KOTLIN — LocalAssistantViewModel.kt
package com.ismartanji.mobileai.ui

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.ismartanji.mobileai.data.OnDeviceAiRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

sealed interface UiState {
    object Idle : UiState
    object Loading : UiState
    data class Success(val outputText: String) : UiState
    data class Error(val message: String) : UiState
}

class LocalAssistantViewModel(
    private val repository: OnDeviceAiRepository
) : ViewModel() {

    private val _uiState = MutableStateFlow<UiState>(UiState.Idle)
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()

    init {
        viewModelScope.launch {
            repository.initializeModel()
                .onFailure { _uiState.value = UiState.Error("Device incompatible or model downloading.") }
        }
    }

    fun summarizeText(inputText: String) {
        viewModelScope.launch {
            _uiState.value = UiState.Loading
            var accumulatedText = ""
            
            try {
                val prompt = "Summarize the following notes concisely in three bullet points:\n$inputText"
                repository.generateStreamingResponse(prompt).collect { token ->
                    accumulatedText += token
                    _uiState.value = UiState.Success(accumulatedText)
                }
            } catch (e: Exception) {
                _uiState.value = UiState.Error("Generation failed: ${e.localizedMessage}")
            }
        }
    }
}

Step 4: Build the Reactive Jetpack Compose UI Screen

Construct a modern Jetpack Compose screen rendering user inputs and live on-device generation results:

KOTLIN (Compose) — OnDeviceAiScreen.kt
package com.ismartanji.mobileai.ui

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun OnDeviceAiScreen(
    viewModel: LocalAssistantViewModel,
    modifier: Modifier = Modifier
) {
    val uiState by viewModel.uiState.collectAsState()
    var userNotes by remember { mutableStateOf("") }

    Scaffold(
        topBar = { TopAppBar(title = { Text("Local Notes AI Assistant") }) },
        modifier = modifier
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .padding(innerPadding)
                .padding(16.dp)
                .fillMaxSize()
                .verticalScroll(rememberScrollState()),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            OutlinedTextField(
                value = userNotes,
                onValueChange = { userNotes = it },
                label = { Text("Paste meeting notes or thoughts") },
                placeholder = { Text("Enter text for instant offline on-device summarization...") },
                modifier = Modifier.fillMaxWidth().height(150.dp)
            )

            Button(
                onClick = { viewModel.summarizeText(userNotes) },
                enabled = userNotes.isNotBlank() && uiState !is UiState.Loading,
                modifier = Modifier.fillMaxWidth()
            ) {
                Text("Summarize with On-Device AI")
            }

            when (val state = uiState) {
                is UiState.Idle -> {
                    Text(
                        text = "Ready for private, zero-latency inference.",
                        style = MaterialTheme.typography.bodyMedium,
                        color = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                }
                is UiState.Loading -> {
                    LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
                    Text("Streaming tokens from local NPU...")
                }
                is UiState.Success -> {
                    Card(
                        colors = CardDefaults.cardColors(
                            containerColor = MaterialTheme.colorScheme.surfaceVariant
                        ),
                        modifier = Modifier.fillMaxWidth()
                    ) {
                        Column(modifier = Modifier.padding(16.dp)) {
                            Text(
                                text = "Local Summary:",
                                style = MaterialTheme.typography.titleMedium
                            )
                            Spacer(modifier = Modifier.height(8.dp))
                            Text(
                                text = state.outputText,
                                style = MaterialTheme.typography.bodyLarge
                            )
                        }
                    }
                }
                is UiState.Error -> {
                    Text(
                        text = state.message,
                        color = MaterialTheme.colorScheme.error,
                        style = MaterialTheme.typography.bodyMedium
                    )
                }
            }
        }
    }
}
Google for Developers page Overview of the ML Kit GenAI APIs, listing summarization, proofreading, rewriting, image description, speech recognition and prompt
Google's ML Kit GenAI APIs, built on Gemini Nano and AICore, which run on the device. Screenshot of the official documentation.

Real-World Production Gotchas and Mobile Constraints

Deploying on-device language models across the fragmented Android device landscape exposes four critical engineering failure modes:

  1. Hardware Incompatibility and Model Availability Latency: Android AICore is not universally available on every budget device. Mid-range and entry-tier devices often lack the requisite NPU TOPS or RAM headroom. Always implement a graceful fallback: check isAvailable() at runtime. If the local model is unavailable or pending initial background download, route critical requests to a lightweight cloud endpoint or provide a standard non-AI fallback UI.
  2. Thermal Throttling and Clock Degradation: Sustained neural model inference generates substantial heat on mobile chipsets. Under continuous sustained inference loops on mobile chipsets, device thermal mitigation kicks in to regulate chassis temperature and protect battery health, causing observed generation throughput to throttle. As documented in Android performance guidelines, mobile applications should restrict generative prompts to bounded output windows (typically under 300 tokens per turn) and register callbacks via PowerManager.OnThermalStatusChangedListener to gracefully throttle background jobs when thermal status reaches THERMAL_STATUS_MODERATE.
  3. The Low Memory Killer (LMK) Threat: Mobile operating systems aggressively terminate background processes when the system faces memory pressure. If an app attempts to allocate a large KV cache buffer while another foreground app launches, the system LMK daemon will terminate your app instantly. Use shared system models via AICore whenever possible, and release model sessions immediately when your activity transitions into the background.
  4. Context Window Limitations on Mobile: Desktop and server LLMs comfortably ingest millions of context tokens. On-device mobile models typically support context windows between 2,048 and 4,096 tokens. Attempting to pass lengthy historical chat transcripts into Gemini Nano triggers silent truncation or memory allocation exceptions. Implement sliding window truncation and extractive token summarization before passing prompts to local models.

Related Technical Resources

Deepen your mobile development and software engineering knowledge with related production guides on ISMARTANJI CREATIONS:

Frequently Asked Questions

What Android operating system version is required to use Android AICore?

Android AICore was introduced in Android 14 and is fully supported on modern devices running Android 15 and current Android releases. Hardware acceleration is provided on devices equipped with dedicated NPU silicon, such as Google Tensor G3/G4, Qualcomm Snapdragon 8 Gen 3/4, and MediaTek Dimensity 9300/9400.

How much larger does an Android app APK become when integrating Gemini Nano?

Integrating Gemini Nano via Android AICore adds virtually zero size to your app’s APK binary (minimal application overhead, as model weights are distributed and updated at the operating system level). Because the model weights are downloaded, updated, and managed globally by the operating system through Google Play system updates, developers do not bundle multi-gigabyte neural network files into their application packages.

Can on-device Android models run without any internet connection?

Yes. Once the base model has been downloaded and initialized by the Android operating system, all inference operations execute 100% locally on the device’s CPU and NPU hardware. The application can generate text, summarize documents, and analyze inputs without cellular or Wi-Fi connectivity.

Android Hardware Support Matrix: AICore vs Edge Fallbacks

Because Android AICore availability is tied to hardware NPU specifications and system image updates, production apps should consult this architectural support matrix:

Device FamilyChipset & NPUAICore / Nano StatusRecommended Fallback
Google Pixel 9 / 9 ProGoogle Tensor G4 (37 TOPS)Pre-installed / ActiveNone required (Direct AICore)
Google Pixel 8 / 8 ProGoogle Tensor G3Enabled via Google Play System UpdatesNone required (Direct AICore)
Samsung Galaxy S24 / S25Snapdragon 8 Gen 3 / Exynos 2400Supported via Galaxy AI system frameworkAICore or MediaPipe GenAI
Mid-Range / Older AndroidsSnapdragon 7-series / DimensityUnavailable in system AICoreLiteRT / MediaPipe GenAI (CPU/GPU)
Legacy Devices (Android < 14)Various legacy architecturesUnsupportedSecure cloud API gateway

Reference: Always verify the latest device eligibility list in the Official Android Developers AICore Guide before publishing updates to the Google Play Store.

Production Deployment Guidelines

  • Step 1: Check Hardware Availability at Runtime — Verify AICore support and model installation status before presenting AI-driven UI features to the user.
  • Step 2: Enforce Strict Output Token Limits — Configure GenerationConfig with maximum output bounds (150–300 tokens) to preserve device battery and prevent thermal throttling.
  • Step 3: Implement Reactive State with Coroutine Flows — Stream generated text tokens directly from the NPU to Jetpack Compose UI state using asynchronous Kotlin Flows.
  • Step 4: Establish Graceful Cloud or Standard Fallbacks — Build automated fallback logic that gracefully handles budget devices lacking dedicated NPU silicon.
  • Step 5: Profile Memory Allocation in Android Studio — Use the Android Studio Memory and Energy Profilers to verify that model execution remains within safe heap thresholds.

Join the Discussion: Are you building on-device AI features for Android or cross-platform mobile apps? How are you handling model fallbacks and memory limits? Share your mobile architecture lessons in the comments below, and explore our complete collection of developer guides at ISMARTANJI CREATIONS.


Sources & Official Documentation

  • Android Developers AICore Documentation: developer.android.com/ai/aicore — System architecture, supported APIs, and device compatibility.
  • Google AI Edge Developer Guide: ai.google.dev/edge — On-device SDKs, LiteRT, and MediaPipe GenAI runtimes.
  • Android Thermal Management APIs: PowerManager API Reference — Monitoring system thermal mitigation events.
  • Test Environment & Versions: Evaluated on Google Pixel 9 Pro (Android 15) using com.google.ai.edge.aicore:aicore:1.0.0-alpha02 and Jetpack Compose BOM 2024+.

Written & Verified by Sampath Anji

Sampath Anji is a technology researcher, systems developer, and digital creator based in Telangana, India. He specializes in on-device AI architectures, autonomous agent workflows, high-throughput inference engines, and digital media production. Every tutorial on ISMARTANJI CREATIONS is grounded in code reproducibility, verified documentation, and transparent test environments. Read our full testing methodology on our About Us page, or submit feedback and code updates via our Contact Desk.

Leave a Comment