Kotlin Multiplatform(KMP)结合 Compose Multiplatform 正在成为跨平台开发的热门选择,它允许开发者用一套代码构建 Android、iOS、桌面(Windows/macOS/Linux)和 Web 应用。以下是一个实战指南,涵盖核心概念和代码示例。

1. 环境搭建

工具要求:

Android Studio 或 IntelliJ IDEA(安装 Kotlin Multiplatform 插件)

Xcode(用于 iOS 编译)

JDK 11+

配置 gradle.properties:kotlin.native.cacheKind=none # 避免 iOS 编译缓存问题

新建项目:使用 Kotlin Multiplatform Wizard 快速生成跨平台项目模板,勾选 Compose Multiplatform 支持。

2. 项目结构

典型的多平台项目结构:

shared/

src/

commonMain/ # 公共代码(Compose UI、业务逻辑)

androidMain/ # Android 平台特定代码

iosMain/ # iOS 平台特定代码

desktopMain/ # 桌面端代码

androidApp/ # Android 应用模块

iosApp/ # iOS Xcode 项目

desktopApp/ # 桌面端启动模块

3. 编写共享 Compose UI

在 shared/src/commonMain/kotlin 中创建跨平台组件:

// 共享的 Compose 组件

@Composable

fun Greeting(name: String) {

Text(

text = "Hello, $name!",

modifier = Modifier.padding(16.dp),

color = Color.Blue

)

}

// 平台无关的 ViewModel

class SharedViewModel {

private val _count = mutableStateOf(0)

val count: State = _count

fun increment() {

_count.value++

}

}

4. 平台适配

Android 端 (androidApp 模块)

直接使用 Compose:

class MainActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContent {

AppTheme { // 自定义主题

Greeting("Android")

}

}

}

}

iOS 端 (iosApp 模块)

通过 UIViewController 嵌入 Compose:

// shared/src/iosMain/kotlin

fun MainViewController(): UIViewController =

ComposeUIViewController {

Greeting("iOS")

}

桌面端 (desktopApp 模块)

fun main() = application {

Window(onCloseRequest = ::exitApplication) {

Greeting("Desktop")

}

}

5. 处理平台差异

使用 expect/actual 机制实现平台特定逻辑:

// 公共代码声明 expect

expect fun getPlatformName(): String

// Android 实现

actual fun getPlatformName(): String = "Android"

// iOS 实现

actual fun getPlatformName(): String = "iOS"

在 Compose 中使用:

@Composable

fun PlatformSpecificGreeting() {

Text("Running on ${getPlatformName()}")

}

6. 状态管理与导航

状态管理:使用 mutableStateOf 或 ViewModel(通过 koin 或 kodein 注入)。

导航:使用 Voyager 或自定义导航逻辑:

sealed class Screen {

object Home : Screen()

object Detail : Screen()

}

@Composable

fun App() {

var currentScreen by remember { mutableStateOf(Screen.Home) }

when (currentScreen) {

is Screen.Home -> HomeScreen { currentScreen = Screen.Detail }

is Screen.Detail -> DetailScreen { currentScreen = Screen.Home }

}

}

7. 资源管理

共享资源:将图片、字体等放在 commonMain/resources,通过路径访问:Image(painterResource("images/logo.png"), "logo")

平台资源:在 androidMain/resources 或 iosMain/resources 放置平台特定资源。

8. 调试与发布

Android:直接通过 Android Studio 运行。

iOS:

生成 Xcode 项目:./gradlew podGen

打开 iosApp/iosApp.xcworkspace 并运行。

桌面端:./gradlew run 或打包为原生应用:./gradlew packageDebian # Linux

./gradlew packageMsi # Windows

./gradlew packageDmg # macOS

9. 常见问题

iOS 编译缓慢:禁用缓存(gradle.properties 中设置 kotlin.native.cacheKind=none)。

字体兼容性:iOS 需手动注册字体(通过 NSDataAsset)。

性能优化:避免在公共代码中使用过多平台差异分支。

10. 学习资源

官方文档

Compose Multiplatform 示例项目

KMP 社区

通过 Compose Multiplatform,开发者可以显著减少重复代码,但需注意平衡代码共享与平台体验。建议从简单模块开始逐步迁移,同时利用 Kotlin 的强类型特性减少运行时错误。