Android 端侧 AI 实战:Gemini Nano 集成指南
2026 年是端侧 AI 从概念走向落地的关键之年。从 Google 的 Gemini Nano 到 Apple 的端侧模型,各厂商都在推动 AI 能力「走出云端」。本文基于我的实际集成经验,深入解析 Android 端侧 AI 的核心方案:Gemini Nano + AICore + ML Kit GenAI API,并提供一个完整的实战案例。
为什么选择端侧 AI?
在将 AI 能力集成到移动应用时,传统方案存在几个显著痛点:
- 网络依赖:需要实时联网,弱网环境下无法使用
- 隐私风险:用户数据需要上传到云端处理
- 延迟抖动:网络状况直接影响响应时间
- 成本不可控:API 调用按量收费,大规模使用成本高昂
端侧 AI(On-Device AI)完美解决以上问题:
- ✅ 完全离线:模型本地运行,无需网络
- ✅ 隐私保护:数据不出设备用户完全掌控
- ✅ 零延迟:本地推理响应即时
- ✅ 零 成本:无 API 调用费用
Gemini Nano 架构解析
Gemini Nano 是 Google 专为端侧运行优化的轻量级模型通过 Android 系统层的 AICore 运行时提供服务。理解这个架构是成功集成的关键。
三层架构
| 层级 | 组件 | 职责 |
|---|---|---|
| 应用层 | ML Kit GenAI API | 高级封装提供简洁的调用接口 |
| 系统层 | AICore | 模型管理、推理调度、NPU 加速 |
| 模型层 | Gemini Nano | 实际的 AI 推理计算 |
AICore 的核心职责
AICore 是 Android 16/17 引入的系统级 AI 运行时它充当 App 与 Gemini Nano 模型的 broker:
- 模型管理:动态下载、更新、缓存模型文件
- 推理调度:将推理任务分配到 NPU/GPU/CPU
- 资源管理:控制模型占用内存避免系统卡顿
- 权限控制:管理哪些 App 可以使用端侧 AI 能力
环境配置
1. 添加依赖
在 build.gradle (app) 中添加 ML Kit 生成式 AI 依赖:
dependencies {
// ML Kit GenAI API (powered by Gemini Nano)
implementation 'com.google.mlkit:genai-common:0.1.0'
implementation 'com.google.mlkit:text-generation:16.0.0'
// 如果需要图像描述功能
implementation 'com.google.mlkit:image-labeling:17.0.7'
}
2. 检查设备兼容性
在调用前检查设备是否支持端侧 AI 能力:
import com.google.mlkit.common.MlKitException
import com.google.mlkit.common.model.RemoteModelManager
import com.google.mlkit.textgeneration.TextGeneration
// 检查设备是否支持
fun checkDeviceSupport(): Boolean {
return try {
// 尝试获取模型管理器
val manager = RemoteModelManager.getInstance()
// 如果能正常获取说明支持
true
} catch (e: MlKitException) {
// 不支持的设备会抛出异常
false
}
}
3. 配置权限
AICore 不需要特殊权限但首次调用会触发模型下载。建议:
- 在 WiFi 环境下首次调用让模型下载完成
- 可以在设置中查看 AI 模型下载状态
功能一:文本摘要
ML Kit 提供文本摘要功能可以将长文本压缩为简洁摘要:
import com.google.mlkit.textgeneration.TextGeneration
import com.google.mlkit.textgeneration.TextGenerator
import com.google.mlkit.textgeneration.TextGeneratorOptions
// 创建生成器
val options = TextGeneratorOptions.Builder()
.setModelType(TextGeneratorOptions.LOCAL_LITE)
.build()
val textGenerator = TextGeneration.getClient(options)
// 生成摘要
fun summarizeText(longText: String) {
val input = "Provide a brief summary of the following text: $longText"
textGenerator.generate(input)
.addOnSuccessListener { result ->
val summary = result.text
Log.d("GeminiNano", "Summary: $summary")
}
.addOnFailureListener { e ->
Log.e("GeminiNano", "Error: ${e.message}")
}
}
完整示例:摘要功能
class Summarizer(private val context: Context) {
private val textGenerator: TextGenerator by lazy {
val options = TextGeneratorOptions.Builder()
.setModelType(TextGeneratorOptions.LOCAL_LITE)
.build()
TextGeneration.getClient(options)
}
fun summarize(
text: String,
onSuccess: (String) -> Unit,
onError: (Exception) -> Unit
) {
// 构建提示词
val prompt = buildPrompt(text)
textGenerator.generate(prompt)
.addOnSuccessListener { result ->
onSuccess(result.text.trim())
}
.addOnFailureListener { e ->
onError(e)
}
}
private fun buildPrompt(text: String): String {
return """
请用不超过 100 字总结以下内容:
$text
摘要:
""".trimIndent()
}
fun close() {
textGenerator.close()
}
}
功能二:文本校对
校对功能可以检测并修正文本中的语法错误和用词问题:
import com.google.mlkit.textgeneration.TextGeneration
// 文本校对
fun proofreadText(text: String) {
val prompt = """
请校对以下文本修正语法错误和用词问题只返回修正后的文本:
$text
""".trimIndent()
textGenerator.generate(prompt)
.addOnSuccessListener { result ->
val corrected = result.text.trim()
Log.d("Proofread", "Corrected: $corrected")
}
.addOnFailureListener { e ->
Log.e("Proofread", "Error: ${e.message}")
}
}
功能三:文本重写
重写功能可以将文本改写成不同风格(如正式、口语化、简洁):
// 风格重写示例
fun rewriteToStyle(text: String, style: String) {
val stylePrompt = when (style) {
"formal" -> "正式"
"casual" -> "口语化"
"concise" -> "简洁"
else -> "保持原样"
}
val prompt = """
请将以下文本改写成$stylePrompt 风格只返回改写后的文本:
$text
""".trimIndent()
textGenerator.generate(prompt)
.addOnSuccessListener { result ->
val rewritten = result.text.trim()
// 处理结果
}
}
功能四:图像描述(进阶)
虽然 ML Kit 的主 API 是文本能力但可以通过组合实现图像理解:
// 结合图像标注实现图像理解
import com.google.mlkit.image labeling.ImageLabeling
import com.google.mlkit.image labeling.defaultImageLabeler
class ImageDescriber(private val context: Context) {
private val imageLabeler = ImageLabeling.getClient(
defaultImageLabelerOptions {
setConfidenceThreshold(0.7f)
}
)
private val textGenerator = TextGeneration.getClient(
TextGeneratorOptions.Builder()
.setModelType(TextGeneratorOptions.LOCAL_LITE)
.build()
)
// 获取图像标签后生成描述
fun describeImage(bitmap: Bitmap) {
imageLabeler.process(bitmap)
.addOnSuccessListener { labels ->
// 提取标签
val tags = labels.joinToString("、") { it.text }
// 使用 Gemini Nano 生成自然语言描述
val prompt = "用一句话描述这张图片包含的要素:$tags"
textGenerator.generate(prompt)
.addOnSuccessListener { result ->
val description = result.text.trim()
Log.d("ImageDesc", description)
}
}
.addOnFailureListener { e ->
Log.e("ImageDesc", e.message ?: "Error")
}
}
}
设备兼容性与踩坑记录
集成过程中我遇到以下问题整理成避坑指南:
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 首次调用特别慢 | 模型需要下载 | 提示用户在 WiFi 下使用或预加载 |
| 返回空结果 | 模型未就绪 | 检查 AICore 状态等待模型下载完成 |
| 抛出 ModuleNotFoundException | 设备不支持 AICore | 回退到云端 API 或提示用户 |
| 内存占用高 | 模型运行在 CPU | 确保设备有足够内存或降低并发 |
兼容性检查工具
// 完整的兼容性检查
object AICoreChecker {
fun checkCompatibility(context: Context): CompatibilityResult {
return try {
// 尝试初始化
val options = TextGeneratorOptions.Builder()
.setModelType(TextGeneratorOptions.LOCAL_LITE)
.build()
val client = TextGeneration.getClient(options)
client.close()
CompatibilityResult(
supported = true,
message = "设备支持端侧 AI"
)
} catch (e: Exception) {
CompatibilityResult(
supported = false,
message = "设备不支持: ${e.message}"
)
}
}
data class CompatibilityResult(
val supported: Boolean,
val message: String
)
}
性能优化建议
1. 模型预加载
// 在 Application 中预加载模型
class MyApp : Application() {
private val textGenerator: TextGenerator by lazy {
TextGeneration.getClient(
TextGeneratorOptions.Builder()
.setModelType(TextGeneratorOptions.LOCAL_LITE)
.build()
)
}
override fun onCreate() {
super.onCreate()
// 预热模型
warmUpModel()
}
private fun warmUpModel() {
// 发送一个空请求预热
textGenerator.generate("Hello")
.addOnSuccessListener { /* 预热完成 */ }
}
}
2. 批量处理
对于多个文本处理使用批量模式减少模型加载开销:
// 不要频繁创建和销毁生成器
class TextProcessor {
// 复用单个生成器实例
private val generator: TextGenerator by lazy {
TextGeneration.getClient(/* options */)
}
// 批量处理
fun processBatch(texts: List) {
// 将多个文本组合成一个请求
val combined = texts.mapIndexed { index, text ->
"${index + 1}. $text"
}.joinToString("\n")
val prompt = "处理以下内容:\n$combined"
// 一次性调用
}
// 使用完后统一释放
fun release() {
generator.close()
}
}
3. 异步处理
模型推理是耗时操作务必在后台线程执行:
// 使用协程处理
fun generateAsync(prompt: String): Deferred {
return CoroutineScope(Dispatchers.IO).async {
try {
textGenerator.generate(prompt).await().text.trim()
} catch (e: Exception) {
throw e
}
}
}
4. 结果缓存
相同输入可以缓存结果避免重复计算:
// 简单的 LRU 缓存
class ResultCache(private val maxSize: Int = 100) {
private val cache = object : LinkedHashMap(maxSize, 0.75f, true) {
override fun removeEldestEntry(eldest: MutableMap.MutableEntry?): Boolean {
return size > maxSize
}
}
fun get(key: String): String? = cache[key]
fun put(key: String, value: String) {
cache[key] = value
}
}
实战案例:智能笔记应用
结合以上所有功能以下是简化的智能笔记应用架构:
class SmartNoteProcessor(
private val context: Context,
private val summarizer: Summarizer,
private val proofreader: Proofreader
) {
// 智能摘要
fun autoSummarize(note: String): String {
// 输入验证
if (note.length < 100) return note
return summarizer.summarize(note)
}
// 自动校对
fun autoProofread(note: String): String {
return proofreader.proofread(note)
}
// 智能处理流程
fun processNote(note: String): ProcessedNote {
val proofread = autoProofread(note)
val summarized = if (note.length > 500) {
autoSummarize(note)
} else null
return ProcessedNote(
original = note,
corrected = proofread,
summary = summarized,
timestamp = System.currentTimeMillis()
)
}
data class ProcessedNote(
val original: String,
val corrected: String,
val summary: String?,
val timestamp: Long
)
}
总结
Gemini Nano 代表了移动端侧 AI 的重要方向通过 ML Kit 的高级 API 开发者可以快速将 AI 能力引入应用而无需关心底层模型管理。但需要注意:
- 设备兼容性:并非所有设备都支持需要优雅降级
- 能力边界:端侧模型能力弱于云端适用于简单任务
- 用户体验:首次加载慢需要做好预期管理
随着 Android 系统的演进和芯片能力的提升端侧 AI 将成为移动开发的标配。建议现在就开始尝试为未来做好准备。