一、 引言: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 将开启下一代智能应用的大门。
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐