Kotlin Multiplatform(KMP)— JetBrains 技术,将通用 Kotlin 代码直接编译为 iOS、Android、Web 和 Desktop。与 Flutter 和 React Native 不同,KMP 不替换原生 UI — 通用逻辑被提取到 shared module 中,每个应用程序的界面保持原生。Kotlin Multiplatform documentation — 配置模块和 expect/actual 机制的主要参考指南。
要点
Kotlin Multiplatform — 交叉编译技术,允许用 Kotlin 编写通用代码并将其编译为不同平台:JVM(Android)、LLVM(iOS、macOS、watchOS)、JavaScript(Web)和原生二进制文件(Linux、Windows)。KMP 不是 UI 框架 — 它解决的是业务逻辑的重用问题,而不是界面。
KMP 的架构围绕 shared module 构建 — 一个 Gradle 模块,包含具有平台无关代码的 commonMain 和针对每个目标的 source sets(androidMain、iosMain、desktopMain)。根据 JetBrains 2025 年的数据,超过 40% 的新 Kotlin 项目使用 KMP 在平台之间共享代码。
Kotlin Multiplatform Mobile(KMM)— 以前用于 iOS+Android 移动场景的名称。从 Kotlin 2.1+ 开始,KMM 术语已被通用 Kotlin Multiplatform 取代,因为该技术已超越移动开发的界限。Netflix、McDonald's 和 VMware 在生产中使用 KMP 在移动应用程序之间共享代码。
Expect/actual — KMP 处理平台代码的关键机制。在 commonMain 中声明 expect 声明(函数、类、属性),在每个特定于平台的 source set(androidMain、iosMain)中声明 actual 实现。编译器检查每个 expect 在每个目标平台上是否有对应的 actual。
// commonMain — 平台 API 的声明
expect fun getPlatformName(): String
expect class PlatformContext(val appVersion: String)
// androidMain — Android 的 actual 实现
actual fun getPlatformName(): String = "Android \${Build.VERSION.SDK_INT}"
// iosMain — iOS 的 actual 实现
actual fun getPlatformName(): String =
UIDevice.currentDevice.systemNameSource sets 层次结构 在 KMP 中允许创建中间层:例如,iosArm64Main(物理 iOS 设备)和 iosSimulatorArm64Main(模拟器)具有共同的 iosMain。来自 commonMain 的代码对所有平台可用,来自 iosMain 的代码仅对 iOS 目标可用。当实现不是每个平台都不同,而是一组平台不同时,这减少了重复。
在实践中,expect/actual 用于:获取本地存储(SharedPreferences vs NSUserDefaults)、网络工作(每个平台的 HttpEngine)、文件系统访问、加密和分析。JetBrains 建议最小化 expect/actual 的数量,并将尽可能多的代码移到 commonMain 中。
Shared module — 带有 `org.jetbrains.kotlin.multiplatform` 插件的标准 Gradle 模块。它在 `src/commonMain/kotlin/` 中包含通用代码,在 `src/androidMain/kotlin/` 和 `src/iosMain/kotlin/` 中包含平台实现。KMP 项目还连接了依赖于 shared module 的 `androidApp` 和 `iosApp`。
// build.gradle.kts — shared module
plugins {
kotlin("multiplatform")
id("com.android.library")
}
kotlin {
androidTarget()
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "shared"
isStatic = true
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.ktor:ktor-client-core:3.1.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
}
}
val androidMain by getting {
dependencies {
implementation("io.ktor:ktor-client-okhttp:3.1.0")
}
}
val iosMain by creating {
dependencies {
implementation("io.ktor:ktor-client-darwin:3.1.0")
}
}
}
}KMP 的 Gradle 配置需要明确指定 iOS 目标 — x64(Intel 模拟器)、arm64(物理设备)和 simulatorArm64(Apple Silicon 模拟器)。为每个目标生成单独的 Apple framework。`kotlin("multiplatform")` 插件根据声明的目标自动配置 JVM 和 LLVM 的编译。
Ktor 和 kotlinx.serialization — 支持通用代码的标准 KMP 库。Ktor 为每个平台提供带有引擎的 HTTP 客户端(Android 使用 OkHttp,iOS 使用 Darwin)。kotlinx.serialization 由于在 commonMain 中的多平台实现,无需 expect/actual 即可在任何平台上运行。
Kotlin/Native — 通过 LLVM 将 Kotlin 编译为原生代码的编译器。对于 iOS,shared module 编译为 Apple framework(.framework),通过 Xcode 连接。从 Swift/Objective-C 调用通用代码通过生成的 Objective-C 头文件进行,因此 shared module 的 API 必须与 Objective-C 兼容。
iOS 集成的限制: Kotlin 集合(List、Map)转换为 NSArray/NSDictionary。具有默认参数的函数不会被导出 — 需要 overloads。对于 suspend 函数,生成基于回调的方法,使用 `@ObjCName` 并从 Kotlin 2.0+ 开始支持 async/await。
// iOS 应用程序:从 Swift 调用 shared module
import shared
class ViewModel: ObservableObject {
let repository = UserRepository()
func loadUsers() {
repository.fetchUsers(completionHandler: { result, error in
if let users = result as? [User] {
print("Users: \(users.count)")
}
})
}
}Shared module 在 Xcode 中的 集成通过 embed-and-framework 完成 — 生成的 `.xcframework` 被添加到 Xcode 项目中。Gradle 插件可以通过 embedAndSignAppleFrameworkForXcode 在构建时自动更新 framework。在模拟器上测试时,iosSimulatorArm64 或 iosX64 二进制文件就足够了。
KMP、Flutter 和 React Native 之间的选择取决于优先级:逻辑重用还是完全跨平台。KMP 在每个平台上提供原生 UI,但需要两个代码库用于界面。Flutter 和 React Native 使用统一的 UI,但牺牲了原生性。
| 特性 | KMP | Flutter | React Native |
|---|---|---|---|
| UI 框架 | 原生(Android XML/Jetpack Compose + SwiftUI) | Dart + 自有 Skia 渲染器 | React + 原生组件 |
| 通用代码 | 业务逻辑、网络、数据库、验证 | 100%(原生插件除外) | 100%(原生模块除外) |
| 性能 | 原生(无中间层) | 高(Skia Engine) | 中(JSI Bridge) |
| iOS 支持 | Kotlin/Native(优秀) | 优秀 | 良好 |
| 入门门槛 | 中(Kotlin + 原生平台) | 低(一种语言 + 一个 UI) | 低(JS/TS + React) |
何时选择 KMP: 项目需要高性能 UI(游戏、地图、动画),需要重用现有原生代码,团队已经熟悉 Kotlin 和原生平台。何时选择 Flutter/RN: 预算有限的 MVP 或初创公司,单一背景的团队,UI 不需要深度原生定制。
KMP 工具 生态系统包括适用于应用程序所有层的库:网络(Ktor)、序列化(kotlinx.serialization)、数据库(SQLDelight)、导航(Decompose)、DI(Koin)和数据存储(multiplatform-settings)。JetBrains 支持 Compose Multiplatform — 一个在所有平台上运行的 Kotlin UI 框架。
// 使用 SQLDelight + Ktor 在 KMP 中的 Repository
class UserRepository(
private val httpClient: HttpClient,
private val db: AppDatabase
) {
suspend fun syncUsers(): List<User> {
val remote = httpClient.get("https://api.example.com/users")
.body<List<UserDto>>()
db.userQueries.replaceAll(remote.map { it.toDomain() })
return db.userQueries.selectAll().executeAsList()
}
}Compose Multiplatform — 基于 Jetpack Compose 的 KMP UI 框架。允许用 Kotlin 为 Android、iOS、Desktop 和 Web 编写界面。2025 年,Compose Multiplatform 在 Android 和 Desktop 上达到稳定状态;iOS 目标处于测试阶段。对于具有原生 UI 的生产项目,KMP 的优势仍然是它与 Flutter 的主要区别。
常见问题
KMM — 是 KMP 针对 iOS 和 Android 的移动场景。从 Kotlin 2.1+ 版本开始,JetBrains 将这两个术语统一为 Kotlin Multiplatform,因为该技术不仅支持移动平台,还支持 Desktop 和 Web。KMM 项目继续运行,但现在已成为通用 KMP 的一部分。
可以。KMP 通过 Kotlin/Native 编译为带有 Objective-C 头文件的 Apple framework。SwiftUI 将此 framework 作为普通库导入。Shared module 导出 Kotlin 类和函数,这些可以从 Swift 调用,但有一些限制(例如,Kotlin 集合会转换为 Foundation 类型)。
在 iOS 上,shared module 通过在 iosTest source set 中的 Kotlin/Native 测试进行测试。对于 UI 测试,在 Xcode 中使用 XCTest 并导入 framework。Kotlin 测试在 commonTest 中用 kotlin.test 编写,并通过 Gradle 任务 iosSimulatorArm64Test 在 iOS 模拟器上执行。
主要的 KMP 库:Ktor(网络)、kotlinx.serialization(JSON)、SQLDelight(数据库)、Koin(DI)、Decompose(导航)、multiplatform-settings(SharedPreferences/NSUserDefaults)、Apollo GraphQL、Firebase(通过 KMP-NativeCoroutines)。Compose Multiplatform 为所有平台提供 UI。
支持。KMP 完全兼容 Gradle 8.5+。从 Kotlin 2.1 开始,官方插件支持 Gradle 8。通过 build.gradle.kts 使用 kotlin("multiplatform") 进行配置需要 Gradle 7.6+,但建议使用 8.5 版本以获得最佳构建性能。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。