Featured image of post Kotlin Multiplatform 跨平台开发指南:Android / iOS / 鸿蒙 / Web / 桌面(2026 学习路线)

Kotlin Multiplatform 跨平台开发指南:Android / iOS / 鸿蒙 / Web / 桌面(2026 学习路线)

如果你打算用 一套 Kotlin 业务代码 覆盖 Android、iOS、桌面、Web,甚至把逻辑延伸到鸿蒙,Kotlin Multiplatform(KMP) 是目前最值得认真投入的技术路线之一。

本文按 2026 年现状(Kotlin 约 2.4.x 文档代)整理:先讲清心智模型,再拆项目结构、expect/actual、Compose Multiplatform、各端落地、鸿蒙现实路径,最后给可执行的 8 周学习计划。目标是让你 能学、能建、能避坑,而不是只收藏一堆链接。

官方入口:Get started with Kotlin Multiplatform


写在前面:先别被「全平台」吓到

KMP 不是 Flutter 那种「一个渲染引擎包打天下」的叙事,也不是「写一次 UI 永远不用管平台」。

更准确的说法是:

  1. 业务逻辑可以高度共享(网络、存储、领域模型、用例、状态机)
  2. UI 可以选择共享,也可以选择原生
  3. 平台能力必须被隔离(文件、相机、推送、权限、系统 UI)
  4. 鸿蒙目前不是 JetBrains 官方一等 target,要单独评估

先接受这四点,后面的学习路径会顺很多。


一、KMP 到底是什么

1.1 一句话定义

Kotlin Multiplatform 让同一份 Kotlin 源码,按目标平台编译成不同产物:

编译后端典型产物常见用途
Kotlin/JVM.class / APK / 桌面应用Android、Desktop
Kotlin/NativeFramework / .so / 可执行文件iOS、macOS 等
Kotlin/JSJS bundle浏览器 / Node(兼容路径)
Kotlin/WasmWasm + JS glue现代 Web 主推方向

1.2 两个关键抽象

Target(目标):告诉 Kotlin「为谁编译」。例如 androidjvmiosArm64wasmJs

Source Set(源集):一组源码 + 依赖 + 编译选项。最常见的是:

  • commonMain:所有平台共享
  • androidMain / iosMain / jvmMain / jsMain / wasmJsMain:平台专用

编译某个平台时,Kotlin 会把 common + 该平台相关 source set 一起编进去。

1.3 产品路线只有两条(先选对)

路线 A:只共享逻辑,UI 各自原生(更稳,大厂常见)

  • shared:网络、DB、业务、状态
  • Android UI:Jetpack Compose / View
  • iOS UI:SwiftUI / UIKit
  • 鸿蒙 UI:ArkUI(ArkTS)
  • Web:React/Vue 等,或 shared 编译为 JS/Wasm 供前端调用
  • 桌面:Compose Desktop 或原生

路线 B:逻辑 + UI 都共享(Compose Multiplatform)

一套 Compose UI 可覆盖:

  • Android
  • iOS
  • Desktop(JVM)
  • Web(Wasm/JS)

鸿蒙不在这条官方主路上。

建议:

  1. 先学路线 A,搞懂 source set / expect-actual / 依赖分层
  2. 再学 Compose Multiplatform
  3. 最后做鸿蒙 spike(实验/社区方案)

二、你要学的知识地图

阶段 1:Kotlin 语言(1–2 周)

必须扎实:

  • 空安全、data classsealed class/interface
  • 集合、高阶函数、扩展函数
  • 协程:suspendFlow、结构化并发
  • kotlinx.serialization
  • 模块与包结构

阶段 2:KMP 核心(1 周)

  • Target / Source Set
  • Default Hierarchy Template(默认层级)
  • expect / actual
  • common 与 platform 依赖
  • 产物形态:AAR、iOS Framework、JVM、Wasm/JS

阶段 3:工程与生态(2–3 周)

  • Gradle Version Catalog
  • Ktor Client
  • SQLDelight
  • Koin(DI)
  • Coil(图片,CMP 生态)
  • Navigation / ViewModel 的多平台化

阶段 4:各端落地(持续)

  • Android 打包与权限
  • iOS Framework 集成(Xcode / SPM / CocoaPods)
  • Desktop 分发
  • Web 打包与浏览器兼容
  • 鸿蒙:共享逻辑桥接到 ArkTS(实验)

三、环境搭建(2026 实用清单)

3.1 通用工具

  • JDK 17 或 21(Temurin / JetBrains Runtime 均可)
  • IntelliJ IDEA + Kotlin Multiplatform IDE Plugin
  • 或 Android Studio(偏移动端)
  • Git

当前官方文档侧 Kotlin 版本大约在 2.4.x(页面可见 2.4.10 一类版本)。
特别注意:KMP 与最新 AGP 不一定同步兼容,不要无点升级 Android Gradle Plugin。

兼容关系以官方为准:
Compatibility guide for Kotlin Multiplatform

3.2 按端额外要求

平台额外要求
AndroidAndroid SDK、模拟器或真机
iOSmacOS + Xcode(硬性)
Desktop无硬性额外依赖;分发包可用 jpackage
Web现代浏览器;调试用 Chrome DevTools
鸿蒙DevEco Studio + HarmonyOS SDK;KMP 需社区/定制链

3.3 最快起步

  1. 打开 KMP Get Started
  2. IDEA:File → New → Project → Kotlin Multiplatform
  3. 初学建议先勾 Android + Desktop,跑通后再加 iOS / Web
  4. 若要四端共享 UI,可按官方教程创建 CMP 应用:
    Create your Compose Multiplatform app

四、项目结构:你必须能看懂的骨架

以 Compose Multiplatform 四端项目为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
ComposeDemo/
├── shared/                 # 共享模块(逻辑 + 可选 UI)
│   └── src/
│       ├── commonMain/
│       ├── androidMain/
│       ├── iosMain/
│       ├── jvmMain/        # 桌面
│       ├── jsMain/
│       ├── wasmJsMain/
│       └── *Test/
├── androidApp/
├── iosApp/                 # Xcode 工程
├── desktopApp/
├── webApp/
├── gradle/
│   └── libs.versions.toml
└── settings.gradle.kts

4.1 Target 声明(概念示例)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// shared/build.gradle.kts
plugins {
    kotlin("multiplatform")
    // android / compose 插件按官方模板添加
}

kotlin {
    android()
    jvm()
    js { browser() }
    wasmJs { browser() }

    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "Shared"
            isStatic = true
        }
    }

    sourceSets {
        commonMain.dependencies {
            // 共享依赖
        }
    }
}

DSL 参考:
Multiplatform Gradle DSL reference

4.2 Source Set 层级(Hierarchy)

声明多个相关 target 后,Gradle 插件会按默认模板自动创建中间层,例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
commonMain
 ├── androidMain
 ├── jvmMain
 ├── nativeMain
 │    └── appleMain
 │         └── iosMain
 │              ├── iosArm64Main
 │              └── iosSimulatorArm64Main
 ├── jsMain
 └── wasmJsMain

好处:

  • iosMain 写一次,多个 iOS 目标共用
  • 编译器保证:某 source set 只能使用 其所有目标都具备 的 API

文档:
Hierarchical project structure


五、核心机制:expect / actual

5.1 规则

  1. commonMainexpect 声明(无实现)
  2. 在各平台 source set 用 actual 实现
  3. 包名、签名必须一致
  4. 编译期按目标合并

文档:
Expected and actual declarations

5.2 最小例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// commonMain
expect fun platformName(): String

// androidMain
actual fun platformName(): String =
    "Android ${android.os.Build.VERSION.SDK_INT}"

// iosMain
import platform.UIKit.UIDevice
actual fun platformName(): String =
    UIDevice.currentDevice.systemName() + " " +
        UIDevice.currentDevice.systemVersion

// jvmMain(Desktop)
actual fun platformName(): String =
    "Desktop JVM ${System.getProperty("os.name")}"

// wasmJsMain / jsMain
actual fun platformName(): String = "Web"

5.3 生产建议:少用 expect,多用接口 + DI

expect/actual 适合薄桥接。业务扩大后,更推荐:

1
2
3
4
5
6
7
interface FileStorage {
    suspend fun save(name: String, bytes: ByteArray)
}

class NoteRepository(
    private val storage: FileStorage
)
  • Android / iOS / Desktop 各自实现 FileStorage
  • 用 Koin 在入口注入

expect/actual 留给:

  • 极薄的平台工厂
  • 路径/时钟/设备信息
  • 无法用接口优雅表达的边界

六、各平台落地

6.1 Android(最成熟)

  • Target:android(JVM)
  • UI:共享 CMP,或原生 Jetpack Compose
  • App 模块:implementation(project(":shared"))

你会用到:

  • Application / Activity 入口
  • 权限、后台、通知
  • 签名与 flavor

注意:

  • 严格跟随 KMP 与 AGP 兼容表
  • 库模块可关注 Google 的 com.android.kotlin.multiplatform.library 演进

6.2 iOS(成熟,但工具链更重)

  • Target:iosArm64 / iosSimulatorArm64
  • shared 编译为 Framework,由 Xcode 链接
  • UI:
    • Share UI:Compose Multiplatform
    • Native UI:SwiftUI 调 Kotlin 业务

集成方式:

  • 本地直接依赖(模板默认)
  • CocoaPods
  • Swift Package Manager
  • 远程预编译 Framework(CI 发布)

文档入口:
Choosing a configuration for your KMP project

Swift 互操作要点:

  • suspend 到 Swift 的桥接要设计清楚
  • 空安全与集合映射
  • 对外暴露精简的 SharedSdk API,不要把整个内部对象图甩给 Swift

硬性限制:编译/签名 iOS 必须 macOS + Xcode。

6.3 Desktop(最适合当学习主场)

  • Target:jvm
  • UI:Compose Multiplatform Desktop
  • 打包:jpackage 等

优势:

  • 调试快
  • 可先在 Desktop 把业务和 UI 跑通,再补移动端

注意:

  • 文件路径、剪贴板、多窗口是桌面特有问题
  • 分发体积(自带运行时)要提前规划

6.4 Web(JS / Wasm)

现状要点:

  • Compose Multiplatform Web 主推 Kotlin/Wasm(wasmJs)
  • js { browser() } 仍可用于兼容与部分生态

常见挑战:

  • 启动体积与下载
  • 浏览器线程模型
  • 资源加载差异
  • SEO 不适合重客户端应用

适合:

  • 管理后台、工具站、与 App 同业务的 Web 客户端

不适合:

  • 强 SEO 的内容官网(官网仍建议静态站)

6.5 鸿蒙 HarmonyOS / OpenHarmony(关键现实)

必须说清楚:

官方 KMP / Compose Multiplatform 目标列表是 Android、iOS、Desktop、Web(JS/Wasm)等,没有官方 ohos / HarmonyOS target。

鸿蒙要用 KMP,现实路径是 社区 / 厂商定制

路径 1:只共享逻辑(务实首选)

1
2
3
4
5
KMP shared(common 业务)
Kotlin/Native(社区 OHOS target / .so)
ArkTS UI 通过 NAPI / 桥接层调用

社区参考:

  • zxystd/Kotlin-OHOS
    为 OpenHarmony / HarmonyOS 适配 Kotlin/Native target,覆盖 stdlib、coroutines、serialization 等;实验性,对主机架构和 SDK 版本绑定较强。

路径 2:腾讯 Kuikly(更偏产品级跨端 UI)

路径 3:鸿蒙原生为主,KMP 只做算法/协议库

商业上通常最稳:

  • 核心算法、协议、校验 → KMP
  • 系统能力、UI、账号、推送 → ArkTS
  • 通过最小 API 表面暴露给鸿蒙

学习建议:

  1. 前两个月不要把鸿蒙当主战场
  2. 先打通 Android + iOS + Desktop(+ Web)
  3. 再单独做「shared 被 ArkTS 调用」的 Hello World spike
  4. 若目标是上架,工期评估要以 ArkUI 原生 + 共享逻辑 为默认,而不是默认 CMP 能直接跑鸿蒙

七、UI 层:Compose Multiplatform

7.1 和 Jetpack Compose 的关系

  • 同一套心智:@ComposablerememberStateModifier、Material3
  • Android 目标实际使用 Google 的 Jetpack 产物
  • 其他平台使用 JetBrains 的 multiplatform 工件

文档:
Relationship between Compose Multiplatform and Jetpack Compose

7.2 最小 UI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Composable
fun App() {
    MaterialTheme {
        var text by remember { mutableStateOf("Hello KMP") }
        Column(Modifier.padding(16.dp)) {
            Text(text)
            Button(onClick = { text = "Clicked on ${platformName()}" }) {
                Text("Click")
            }
        }
    }
}

7.3 资源

使用 compose multiplatform resources(生成 Res 访问器),不要假设 Android 的 R 能在 common 使用。
Resources overview

7.4 平台差异清单(建议单独做笔记)

  • 系统返回 / 手势返回
  • 状态栏与安全区
  • 权限弹窗与文件选择
  • 键盘与焦点
  • 滚动手感
  • 桌面快捷键与窗口
  • Web 路由与浏览器历史

共享 UI 的正确目标不是「100% 长得一样」,而是「业务一致、体验平台化」。


八、业务层推荐架构

推荐简洁的分层 + 单向数据流:

1
2
3
4
5
6
7
commonMain
├── domain/          # 实体、用例、仓库接口
├── data/            # repository 实现、DTO、mapper
│   ├── network/     # Ktor
│   └── db/          # SQLDelight
├── presentation/    # ViewModel / Store / UiState
└── di/              # Koin modules

8.1 网络:Ktor Client

1
2
3
4
5
val client = HttpClient {
    install(ContentNegotiation) {
        json(Json { ignoreUnknownKeys = true })
    }
}

各端 engine 不同:

  • Android:CIO / OkHttp / Android
  • iOS:Darwin
  • JVM:CIO / OkHttp
  • JS/Wasm:对应 JS 引擎

官方相关教程:
Create a multiplatform app using Ktor and SQLDelight

8.2 数据库:SQLDelight

  • common 写 .sq
  • 各端 driver 不同
  • 类型安全 SQL,很适合 KMP

8.3 异步与状态

  • Repository 返回 Flow
  • ViewModel 暴露 StateFlow<UiState>
  • UI 收集状态并渲染

8.4 序列化

  • 优先 kotlinx.serialization
  • 避免在 common 使用偏 JVM 的 Gson / Moshi

九、测试策略

9.1 优先 commonTest

  • 依赖 kotlin.test
  • 领域逻辑、mapper、纯函数必须有测试

9.2 平台测试补边界

  • Android 仪器测试 / JVM 测试
  • iOS Kotlin/Native tests 或上层 XCTest
  • Desktop/JVM 用常规单元测试

教程:
Test your multiplatform app

原则:

能在 commonTest 测的,绝不拖到 UI 测。
跨端 bug 大多来自「平台 API 误入 common」和「协程/状态竞态」。


十、依赖与版本管理

10.1 Version Catalog 思路

gradle/libs.versions.toml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[versions]
kotlin = "2.4.10"
coroutines = "1.10.x"
ktor = "3.x"
serialization = "1.x"
sqldelight = "2.x"
koin = "4.x"

[libraries]
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }

[plugins]
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }

版本号请以你创建项目时的官方模板与兼容表为准,不要死抄过期数字。

10.2 找库

  • klibs.io
  • 引入前先确认支持哪些 target(「有 Android 无 iOS」很常见)

10.3 升级原则

  1. 先升 Kotlin,再升 Compose Multiplatform,再升 Ktor
  2. 一次只动一个大版本
  3. 看 changelog 与兼容表
  4. iOS 模拟器 + 真机都打一遍

十一、8 周可执行学习计划

第 1–2 周:Kotlin + 第一个 KMP

  • Kotlin 语法与协程过一遍
  • 新建 Android + Desktop 项目
  • common 写 Greeting + expect platformName
  • 两端都跑通

第 3 周:网络与数据

  • Ktor GET 公开 API
  • serialization 解析 JSON
  • SQLDelight 本地缓存
  • Repository + UiState

第 4 周:Compose Multiplatform UI

  • 列表页 + 详情页
  • 主题与资源
  • 加载 / 空 / 错误态
  • Desktop 上高效迭代

第 5 周:上 iOS

  • 配置 Xcode
  • Framework 集成
  • 模拟器运行
  • 至少解决一次签名/配置问题

第 6 周:Web

  • 启用 wasmJs
  • 浏览器跑同一套 UI
  • 观察包体与启动时间

第 7 周:架构升级

  • 多 module:core / feature-home / feature-settings
  • Koin DI
  • 日志与崩溃上报抽象
  • CI 编译 Android + Desktop + 单测

第 8 周:鸿蒙 Spike(可选)

  • 阅读 Kotlin-OHOS / Kuikly 文档
  • 只做:common 函数被 ArkTS 调用
  • 记录:不可用库、构建成本、API 暴露方式
  • 决定产品是否真要上鸿蒙共享

十二、第一个真实小项目选题

做一个多端 「收藏夹 / 稍后读」

功能:

  • 假登录或本地用户
  • 列表、搜索、标签
  • 网络拉取 + 本地缓存
  • 设置页(主题、清理缓存)

平台推进顺序:

  1. Desktop(开发主场)
  2. Android
  3. iOS
  4. Web
  5. 鸿蒙只接 shared 逻辑(可选)

这个题目刚好覆盖网络、DB、状态、导航、资源、平台文件清理。


十三、常见坑

  1. java.io.File 写进 commonMain
  2. 乱升 AGP / Xcode / Kotlin
  3. iOS 只测模拟器,真机再爆
  4. 共享 UI 追求像素级一致,反而体验差
  5. expect/actual 滥用,不抽接口
  6. 单模块 shared 无限膨胀,编译变慢
  7. 协程作用域泄漏
  8. 默认以为鸿蒙能在向导里直接勾选
  9. 把 Web 当成 SEO 官网技术方案
  10. 忽略 iOS framework / Wasm / Desktop 运行时体积

十四、官方与扩展资源

官方必读

鸿蒙相关(社区 / 厂商)


十五、立项时怎么选

需求建议
Android + iOS,要极致原生体验KMP 共享逻辑 + 双端原生 UI
Android + iOS + Desktop 快速出货KMP + Compose Multiplatform
还要 Web 管理端CMP + wasmJs(接受 App 式 Web)
必须鸿蒙上架且工期紧ArkUI 原生为主;KMP 只共享非 UI 核心
强图形 / 游戏别硬上 CMP
已有大型 Android 应用渐进抽取 shared 模块
团队 Kotlin 薄弱先补 Kotlin,再上 KMP

十六、今天就能做的 6 步

  1. 安装 IDEA + KMP 插件 + JDK 17/21
  2. 用向导创建项目:Android + Desktop
  3. 跑通按钮点击显示 platformName()
  4. 接入 Ktor 调一个公开 JSON API
  5. SQLDelight 缓存并展示列表
  6. 成功后再加 iOS,再加 Web,鸿蒙最后做 spike

结语

  • KMP 的胜负手是共享业务,不是盲目共享一切 UI。
  • Android / iOS / Desktop / Web 是官方主航道。
  • 鸿蒙 可做,但目前是 社区/定制链,优先「共享逻辑 + ArkUI」。
  • 学习顺序建议:

Kotlin → 工程结构 → expect/actual → 数据层 → Compose Multiplatform → iOS → Web → 鸿蒙 spike

如果你正在把 Android 工程迁到 KMP,或准备用 Compose Multiplatform 做首个四端 Demo,可以从「只加 Desktop 调试面」开始——这通常是投入产出比最高的第一步。


版本说明:本文基于 2026 年公开文档与生态现状整理,具体版本号请以创建工程时的官方模板和兼容表为准。鸿蒙相关方案演进较快,落地前务必复核社区仓库与 SDK 版本。

build with Hugo, theme Stack, visits 0