KMP全栈开发:从Android到AI Agent的技术演进与实践
·
一、 引言:KMP技术栈的崛起与全栈愿景
Kotlin Multiplatform (KMP) 作为 JetBrains 推出的跨平台解决方案,正从移动端(Android/iOS)向更广阔的全栈领域演进。本文将探讨如何利用 KMP 构建从移动前端到服务端,乃至集成 AI Agent 能力的现代全栈应用。
二、 KMP 核心概念与技术选型
- 共享业务逻辑 (Shared Business Logic):使用 Kotlin 编写一次,运行于 JVM、Native、JS 等多平台。
- 预期与实际声明 (expect/actual):跨平台代码的抽象与平台特定实现。
- Compose Multiplatform:声明式 UI 框架,统一 Android、Desktop、Web 界面开发。
- Ktor:异步 HTTP 框架,用于构建共享的网络层与后端服务。
三、 第一站:夯实 Android 与 iOS 移动端基础
- 架构模式:在共享模块中实现 MVVM/MVI,使用 Koin 或 Kodein 进行依赖注入。
- 数据层共享:使用 SQLDelight 实现跨平台数据库,Ktor Client 处理网络请求。
- UI 层适配:Android 使用 Jetpack Compose,iOS 通过 SwiftUI 或 UIKit 桥接。
- 实战案例:构建一个双平台(Android/iOS)的笔记应用,共享数据模型、仓库与业务逻辑。
// 共享模块中的 Note 数据模型
// 使用 Kotlin 的 data class 定义,可在所有平台共享
data class Note(
val id: String = UUID.randomUUID().toString(),
val title: String,
val content: String,
val createdAt: Long = System.currentTimeMillis(),
val updatedAt: Long = System.currentTimeMillis(),
val tags: List<String> = emptyList()
) {
// 跨平台序列化支持(可用于网络传输或本地存储)
fun toJson(): String = Json.encodeToString(this)
companion object {
fun fromJson(json: String): Note = Json.decodeFromString(json)
}
}
// 共享仓库接口定义
interface NoteRepository {
suspend fun getAllNotes(): List<Note>
suspend fun saveNote(note: Note): Boolean
suspend fun deleteNote(id: String): Boolean
}
// 平台特定实现通过 expect/actual 机制提供
expect class PlatformNoteRepository() : NoteRepository
四、 迈向全栈:使用 KMP 开发后端服务
- 为什么选择 Ktor?:纯 Kotlin、协程友好、与前端技术栈统一。
- 构建 RESTful API:设计路由、处理请求、返回 JSON 响应。
- 数据库集成:在 JVM 目标上使用 Exposed 或 JOOQ 连接 PostgreSQL/MySQL。
- 身份验证与授权:实现 JWT 认证,并在共享模块中定义安全模型。
- 实战案例:为上述笔记应用开发一个 Ktor 后端,提供用户管理与数据同步 API。
// Ktor 后端路由定义 - 与前端共享相同的 Note 模型
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
// 在共享模块中定义的路由接口,后端实现具体逻辑
fun Application.configureNoteRoutes(noteRepository: NoteRepository) {
routing {
route("/api/notes") {
// 获取所有笔记
get {
val notes = noteRepository.getAllNotes()
call.respond(notes)
}
// 创建新笔记
post {
val note = call.receive<Note>()
val saved = noteRepository.saveNote(note)
call.respond(mapOf("success" to saved, "id" to note.id))
}
// 更新笔记
put("/{id}") {
val id = call.parameters["id"] ?: throw BadRequestException("Missing id")
val note = call.receive<Note>().copy(id = id)
val updated = noteRepository.saveNote(note)
call.respond(mapOf("success" to updated))
}
// 删除笔记
delete("/{id}") {
val id = call.parameters["id"] ?: throw BadRequestException("Missing id")
val deleted = noteRepository.deleteNote(id)
call.respond(mapOf("success" to deleted))
}
}
// 用户认证路由(使用共享的 JWT 配置)
route("/api/auth") {
post("/login") {
// 共享的认证逻辑
val token = authenticateUser(call.receive<LoginRequest>())
call.respond(mapOf("token" to token))
}
}
}
}
五、 统一界面:Compose Multiplatform 覆盖 Desktop 与 Web
- Desktop Compose:开发 Windows/macOS/Linux 原生桌面客户端。
- Web Compose (via Kotlin/JS):将 UI 编译为 JavaScript,运行在浏览器中。
- 状态与导航共享:在共享模块中管理应用状态与导航逻辑。
- 实战案例:将笔记应用的 UI 扩展到桌面端和 Web 端,实现真正的全平台覆盖。
// Compose Multiplatform 共享 UI 组件
// 这段代码可在 Android、Desktop、Web 上运行
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
// 共享的笔记列表组件
@Composable
fun NoteListScreen(
notes: List<Note>,
onNoteClick: (Note) -> Unit,
onAddNote: () -> Unit
) {
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
// 标题栏 - 在所有平台显示一致
TopAppBar(
title = { Text("我的笔记") },
actions = {
IconButton(onClick = onAddNote) {
Icon(Icons.Default.Add, "添加笔记")
}
}
)
// 笔记列表
LazyColumn {
items(notes) { note ->
NoteItem(
note = note,
onClick = { onNoteClick(note) }
)
}
}
}
}
// 共享的笔记项组件
@Composable
fun NoteItem(note: Note, onClick: () -> Unit) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
onClick = onClick
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = note.title,
style = MaterialTheme.typography.h6
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = note.content.take(100) + if (note.content.length > 100) "..." else "",
style = MaterialTheme.typography.body2,
maxLines = 2
)
// 标签显示
if (note.tags.isNotEmpty()) {
Spacer(modifier = Modifier.height(8.dp))
FlowRow {
note.tags.forEach { tag ->
Chip(
label = { Text(tag) },
modifier = Modifier.padding(end = 4.dp)
)
}
}
}
}
}
}
// 平台特定的入口点通过 expect/actual 实现
expect fun getPlatformName(): String
六、 融入智能:为 KMP 应用集成 AI Agent 能力
- AI Agent 架构概述:智能体作为系统的“协作者”,处理复杂任务与决策。
- 共享的 AI 交互层:在 KMP 共享模块中定义与 AI 服务(如 OpenAI API)通信的接口。
- 平台特定集成:
- 移动端:实现语音输入、摄像头图像分析(调用平台 SDK)。
- 服务端:执行耗时的模型推理、知识库检索(RAG)。
- 桌面/Web 端:提供丰富的交互界面展示 AI 思考过程与结果。
- 实战案例:为笔记应用添加“智能摘要”与“内容分类”AI Agent,用户在全平台都能使用。
// 共享模块中的 AI Agent 接口定义
// 使用 KMP 的 expect/actual 机制,不同平台提供具体实现
import kotlinx.serialization.Serializable
// AI 服务请求/响应模型(可跨平台序列化)
@Serializable
data class AISummaryRequest(
val content: String,
val maxLength: Int = 200,
val language: String = "zh"
)
@Serializable
data class AISummaryResponse(
val summary: String,
val keyPoints: List<String>,
val confidence: Float
)
@Serializable
data class AIClassificationRequest(
val content: String,
val categories: List<String>
)
@Serializable
data class AIClassificationResponse(
val category: String,
val confidence: Float,
val reasoning: String? = null
)
// 共享的 AI Agent 接口
interface AIAgent {
suspend fun summarize(request: AISummaryRequest): Result<AISummaryResponse>
suspend fun classify(request: AIClassificationRequest): Result<AIClassificationResponse>
suspend fun generateTags(content: String): Result<List<String>>
}
// 在共享模块中扩展 Note 类,添加 AI 能力
fun Note.generateSummary(aiAgent: AIAgent): Deferred<AISummaryResponse> {
return CoroutineScope(Dispatchers.Default).async {
aiAgent.summarize(AISummaryRequest(this@generateSummary.content)).getOrThrow()
}
}
fun Note.classifyContent(aiAgent: AIAgent, categories: List<String>): Deferred<AIClassificationResponse> {
return CoroutineScope(Dispatchers.Default).async {
aiAgent.classify(AIClassificationRequest(this@classifyContent.content, categories)).getOrThrow()
}
}
// 平台特定的 AI 实现
expect class OpenAIAgent(apiKey: String) : AIAgent {
// 移动端:可能使用设备本地模型或云端 API
// 服务端:直接调用 OpenAI API 或本地部署的模型
// Web 端:通过 WebSocket 或 REST API 与后端通信
}
// 在笔记仓库中添加 AI 增强功能
class EnhancedNoteRepository(
private val noteRepository: NoteRepository,
private val aiAgent: AIAgent
) : NoteRepository by noteRepository {
suspend fun getNotesWithSummary(): List<Pair<Note, AISummaryResponse>> {
val notes = getAllNotes()
return notes.map { note ->
note to aiAgent.summarize(AISummaryRequest(note.content)).getOrNull()
}.filter { it.second != null }.map { it.first to it.second!! }
}
}
七、 工程化与部署:构建、测试与发布
- 多平台构建配置:使用 Gradle 管理不同目标的依赖与构建任务。
- 持续集成/持续部署 (CI/CD):配置 GitHub Actions 或 GitLab CI 实现自动化构建、测试与发布。
- 性能监控与调试:跨平台的日志收集、性能 profiling 工具链。
- 发布到各平台商店/渠道:Google Play, App Store, 桌面应用商店,Web 部署。
八、 挑战、最佳实践与未来展望
- 常见挑战与解决方案:平台差异处理、二进制大小优化、第三方库兼容性。
- 团队协作最佳实践:模块化设计、API 契约先行、前后端同构开发。
- KMP 生态与未来:Compose Multiplatform 的成熟度、Wasm 目标的支持、与 Flutter 的对比思考。
- 总结:KMP 为实现“一次编写,处处运行”的全栈梦想提供了坚实路径,结合 AI Agent 将开启下一代智能应用的大门。
更多推荐


所有评论(0)