
Kotlin + Compose + Multiplatform
跨平台愈发成熟,性能与原生画上等号
一、前言
Kotlin + Compose + Multiplatform
跨平台方案到2025年来愈发成熟:
-
前景更加值得期待
Google
已经与JetBrains
深度合作,推动Jetpack Compose
与Compose Multiplatform
的API统一,2025年Kotlin 2.1
版本通过K2编译器实现全平台后端优化,显著提升性能与开发体验企业级应用验证成熟度:麦当劳、Netflix等企业已在生产环境实现80%+业务逻辑复用,证明其大规模应用可行性
-
拥有多平台覆盖能力
支持
Android/iOS/桌面/Web/服务器五端
代码共享,Compose Multiplatform
进一步实现UI层跨平台,但需注意部分Jetpack库的兼容性局限与Flutter差异化定位
:KMP通过编译原生二进制(非虚拟机)保留平台特性,适合渐进式改造现有原生项目 -
开发效率显著提升
声明式UI(
Compose
)与协程异步处理的结合,减少模板代码量,同步推进多平台开发,灵活的代码共享策略:可仅共享业务逻辑(如网络层),或扩展至UI层,适应不同项目阶段需求
-
性能与原生体验划上等号
直接编译为平台原生代码(
iOS机器码/Android字节码
等),避免跨平台方案的运行时性能损耗, 支持原生API调用,如:SwiftUI/UIKit集成
,确保平台特定功能的用户体验一致性 -
本文带领大家来一次
Kotlin + Compose + Multiplatform
跨平台之桌面端
实现完整案例:
1)包含新项目工程,配置,打包
2)基础布局,文字显示,图标,图片展示
3)自定义标题栏,拖动,放大,缩小等
4)换肤皮肤等
5)类似Android中ViewModel使用
6)网络和IO文件
7)UI之页面切换Page,和路由跳转
8) 打开文件选择
9) 音乐播放,音频数据展示效果,歌词展示
10)视频播放相关操作
11)KV存储使用
12)数据库使用
-
因为
Kotlin + Compose + Multiplatform
跨平台开发大多数都是从Android
开发者转过来的,对于Android
开发者,Android
相关的配置,Android
相关的知识,如Kotlin ,协程,Compose
都是必备基础,所以这方面的不做过细致的介绍。
二、创建新项目工程,配置,打包
- 使用 Kotlin Multiplatform Wizard 快速生成跨平台项目模板
- 项目工程截图介绍:
androidMain
:Android 平台特定差异代码
commonMain
:所用平台公共代码
iosMain
:IOS平台特定差异代码
jvmMain
:Window/Mac/Linux平台特定差异代码
wasmJsMain
:Web端平台特定差异代码 - 通过使用
expect/actual
机制实现平台特定逻辑,如下:
- 3.1)
commonMain
公共模块下定义:
kotlin
//定义
interface Platform {
val name: String
}
expect fun getPlatform(): Platform
//实现获取调用
class Greeting {
private val platform = getPlatform()
fun greet(): String {
return "Hello, ${platform.name}!"
}
}
//界面里面调用使用
AnimatedVisibility(showContent) {
val greeting = remember { Greeting().greet() }
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(painterResource(Res.drawable.compose_multiplatform), null)
Text("Compose: $greeting")
}
}
- 3.2)
androidMain
平台下面实现:
kotlin
class AndroidPlatform : Platform {
override val name: String = "Android ${Build.VERSION.SDK_INT}"
}
actual fun getPlatform(): Platform = AndroidPlatform()
- 3.3)
Window/Mac/Linux
平台下面实现
kotlin
class JVMPlatform: Platform {
override val name: String = "Java ${System.getProperty("java.version")}"
}
actual fun getPlatform(): Platform = JVMPlatform()
- 相关依赖配置:

- 4.1)
androidMain.dependencies{}
下面加入Android平台特定的相关依赖 - 4.2)
commonMain.dependencies {}
下面是加入所有平台都通用的相关依赖 - 4.3)
jvmMain.dependencies {}
下面是加入桌面平台(Window/Mac/Linux
)特定相关的依赖
- 各平台打包相关配置:
- 5.1)
android {}
:下面是Android 打包相关配置,对于熟悉Android的,这个不用介绍了,大家都很熟悉 - 5.2)
compose.desktop {}
:下面是桌面端打包相关配置如下:
arduino
compose.desktop {
application {
mainClass = "com.wx.music.MainKt"//桌面端启动类入口
nativeDistributions {
// targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
targetFormats(TargetFormat.Exe)//桌面端打包exe的后缀
includeAllModules = true // 包含所有依赖
jvmArgs += listOf("-Dfile.encoding=UTF-8,--add-opens=java.base/java.lang=ALL-UNNAMED")
// 指定捆绑的 JRE 版本和路径
javaHome = "C:\Users\XXXX\.jdks\openjdk-21.0.1"//把相关jdk环境打包到exe程序内部
packageName = "WX音乐"//exe程序桌面端名称
packageVersion = "1.0.0"//程序版本
// 启用桌面快捷方式(Windows/Linux)
windows {
iconFile.set(project.file("src/desktopMain/composeResources/drawable/qwer.ico"))//设置桌面端程序图标,注意ico文件格式
shortcut = true//安装生成桌面快捷方式,默认没有的
menu = true //快捷方式加入程序菜单栏,默认没有的
}
// modules("java.desktop") // 图片处理所需模块
}
buildTypes.release.proguard {
isEnabled = false // 禁用混淆
}
}
}
打包配置主要包含了:
- 5.3)、
mainClass
:桌面端启动类入口 - 5.4)、
targetFormats
:打包桌面端后缀格式:.exe是Windows
,.Dmg是Mac os下的安装app后缀文件
,Linux 系统下 Debian/Ubuntu 等发行版软件包的标准格式
- 5.5)、
includeAllModules = true
是控制打包所有包含所有依赖进入安装程序 - 5.6)、
jvmArgs += listOf("-Dfile.encoding=UTF-8,--add-opens=java.base/java.lang=ALL-UNNAMED")
:主要是-Dfile.encoding=UTF-8
强制 JVM 使用 UTF-8 编码处理文件读写和字符串操作,避免因系统默认编码不一致导致的乱码问题,--add-opens=java.base/java.lang=ALL-UNNAMED
允许未命名模块通过反射访问java.base
模块下的java.lang
包内部 API,解决 Java 9+ 模块化系统导致的反射访问限制问题 - 5.7)、通过
javaHome
配置指定捆绑的 JRE 版本和路径,让你把相关jdk环境打包到exe程序内部,安装后可以直接使用 - 5.8)、
packageName
:桌面端名称 - 5.9)、
packageVersion
:程序版本 - 5.10)、通过
iconFile.set(project.file("src/desktopMain/composeResources/drawable/qwer.ico"))
设置桌面端程序图标,注意ico
文件格式 - 5.11)、
shortcut = true:
:安装生成桌面快捷方式,默认没有的 - 5.12)、
menu = true
:快捷方式加入程序菜单栏,默认没有的 - 5.13)、
buildTypes.release.proguard { isEnabled = false // 禁用混淆 }
:在这里面配置相关混淆,或者禁用混淆。
- 怎么打包? 如下图:
- 6.1)
package
:基础打包任务,需配合具体格式参数使用,配置了几个,就把几个包一起打出来 - 6.2)
packageDeb
:打包成Linux
系统.deb
安装包 - 6.3)
packageDistributionForCurrentOS
:智能打包任务,根据当前操作系统自动选择格式 - 6.4)
packageDmg
:打包成Mac
系统.dmg
安装包 - 6.5)
packageExe
:打包成Windows
系统.exe
安装包 - 6.6)
带Release
:就是打包成相关系统下的Release包
- 打包后生成的文件在哪儿?
三、基础布局,文字显示,图标,图片展示
- 基础布局,文字显示,和
Android Jetpact Compose UI
写法完全一样。这里不做过多介绍。 - 本地资源存放位置:
- 2.1、
drawable下面存放svg的xml
- 2.2、
images下面存放图片,png,jpg,webp
- 本地svg使用:
Icon + painterResource("drawable/baseline_minimize_24.xml")
,通过tint
设置图标颜色
ini
Icon(
modifier = Modifier.padding(0.dp, 0.dp, 80.dp, 0.dp).clickable {
minRequest.invoke()
}.size(40.dp).padding(0.dp, 0.dp, 0.dp, 15.dp).align(Alignment.TopEnd),
painter = painterResource("drawable/baseline_minimize_24.xml"),
contentDescription = "关闭",
tint = MaterialTheme.colorScheme.onPrimary
)
- 本地图标使用:
painterResource("images/ic_window_close.webp")
5. 本地图片使用:可使用compose的 Image Icon
配合painterResource("images/ic_window_close.webp")
加载本地图片 6. 网络图片:需要引入下面内容,它是跨平台支持:支持 Android、iOS、JVM(桌面端)、JavaScript 和 WASM 平台
- 6.1、引入下面三方库:
scss
implementation("io.coil-kt.coil3:coil-compose:3.0.3") // 核心Compose支持 支持 Android、iOS、JVM(桌面端)、JavaScript 和 WASM 平台
implementation("io.coil-kt.coil3:coil-network-okhttp:3.0.3")//支持 Android、iOS、JVM(桌面端)、JavaScript 和 WASM 平台
- 6.2、UI界面调用:
less
AsyncImage(
model = item.pic, contentDescription = "Network Image", modifier = Modifier.fillMaxSize().clip(RoundedCornerShape(10)), contentScale = ContentScale.Crop
)
五、总结
本文重点介绍了:
完整案例:Kotlin+Compose+Multiplatform
跨平台之桌面端实现
1)包含新项目工程,配置,打包
2)基础布局,文字显示,图标,图片展示
剩下的将会在接下来的文章进行详细介绍:
3)自定义标题栏,拖动,放大,缩小等
4)换肤皮肤等
5)类似Android中ViewModel使用
6)网络和IO文件
7)UI之页面切换Page,和路由跳转
8) 打开文件选择
9) 音乐播放,音频数据展示效果,歌词展示
10)视频播放相关操作
11)KV存储使用
12)数据库使用
相信本文,或者本系列会给你带来一定的帮助。