完整案例:Kotlin+Compose+Multiplatform跨平台之桌面端实现(一)

Kotlin + Compose + Multiplatform跨平台愈发成熟,性能与原生画上等号

一、前言

Kotlin + Compose + Multiplatform跨平台方案到2025年来愈发成熟:

  1. 前景更加值得期待
    Google已经与JetBrains深度合作,推动Jetpack ComposeCompose Multiplatform的API统一,2025年Kotlin 2.1版本通过K2编译器实现全平台后端优化,显著提升性能与开发体验

    企业级应用验证成熟度:麦当劳、Netflix等企业已在生产环境实现80%+业务逻辑复用,证明其大规模应用可行性

  2. 拥有多平台覆盖能力

    支持Android/iOS/桌面/Web/服务器五端代码共享,Compose Multiplatform进一步实现UI层跨平台,但需注意部分Jetpack库的兼容性局限

    与Flutter差异化定位:KMP通过编译原生二进制(非虚拟机)保留平台特性,适合渐进式改造现有原生项目

  3. 开发效率显著提升

    声明式UI(Compose)与协程异步处理的结合,减少模板代码量,同步推进多平台开发,

    灵活的代码共享策略:可仅共享业务逻辑(如网络层),或扩展至UI层,适应不同项目阶段需求

  4. 性能与原生体验划上等号

    直接编译为平台原生代码(iOS机器码/Android字节码等),避免跨平台方案的运行时性能损耗, 支持原生API调用,如:SwiftUI/UIKit集成,确保平台特定功能的用户体验一致性

  5. 本文带领大家来一次Kotlin + Compose + Multiplatform跨平台之桌面端实现完整案例:
    1)包含新项目工程,配置,打包
    2)基础布局,文字显示,图标,图片展示
    3)自定义标题栏,拖动,放大,缩小等
    4)换肤皮肤等
    5)类似Android中ViewModel使用
    6)网络和IO文件
    7)UI之页面切换Page,和路由跳转
    8) 打开文件选择
    9) 音乐播放,音频数据展示效果,歌词展示
    10)视频播放相关操作
    11)KV存储使用
    12)数据库使用

  6. github地址

  7. 因为Kotlin + Compose + Multiplatform跨平台开发大多数都是从Android开发者转过来的,对于Android 开发者,Android 相关的配置,Android 相关的知识,如Kotlin ,协程,Compose都是必备基础,所以这方面的不做过细致的介绍。

二、创建新项目工程,配置,打包

  1. 使用 Kotlin Multiplatform Wizard 快速生成跨平台项目模板
  2. 项目工程截图介绍:

    androidMain:Android 平台特定差异代码
    commonMain:所用平台公共代码
    iosMain:IOS平台特定差异代码
    jvmMain:Window/Mac/Linux平台特定差异代码
    wasmJsMain:Web端平台特定差异代码
  3. 通过使用 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()
  1. 相关依赖配置:
  • 4.1)androidMain.dependencies{} 下面加入Android平台特定的相关依赖
  • 4.2)commonMain.dependencies {} 下面是加入所有平台都通用的相关依赖
  • 4.3)jvmMain.dependencies {} 下面是加入桌面平台(Window/Mac/Linux)特定相关的依赖
  1. 各平台打包相关配置:
  • 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 // 禁用混淆 }:在这里面配置相关混淆,或者禁用混淆。
  1. 怎么打包? 如下图:
  • 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包
  1. 打包后生成的文件在哪儿?

三、基础布局,文字显示,图标,图片展示

  1. 基础布局,文字显示,和Android Jetpact Compose UI写法完全一样。这里不做过多介绍。
  2. 本地资源存放位置:
  • 2.1、drawable下面存放svg的xml
  • 2.2、images下面存放图片,png,jpg,webp
  1. 本地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
)
  1. 本地图标使用: 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)数据库使用

相信本文,或者本系列会给你带来一定的帮助。

感谢阅读:

欢迎用你发财的小手 关注,点赞、收藏

这里你会学到不一样的东西

相关推荐
一笑的小酒馆43 分钟前
Android15适配和Google上架问题
android
智江鹏2 小时前
Android 之 MVP架构
android
伽蓝_游戏4 小时前
Unity UI的未来之路:从UGUI到UI Toolkit的架构演进与特性剖析(6)
游戏·ui·unity·架构·c#·游戏引擎·.net
文火冰糖的硅基工坊5 小时前
[硬件电路-138]:模拟电路 - 什么是正电源?什么是负电源?集成运放为什么有VCC+和VCC-
单片机·嵌入式硬件·架构·电路·运放·跨学科融合
经典19926 小时前
从单体到分布式:解锁架构进化密码
分布式·架构
未来之窗软件服务6 小时前
企业自动化交互体系的技术架构与实现:从智能回复到自动评论—仙盟创梦IDE
架构·自动化·交互·仙盟创梦ide·东方仙盟
2501_915909066 小时前
Charles中文版使用教程 高效抓包与API调试常见问题处理
android·ios·小程序·https·uni-app·iphone·webview
智江鹏7 小时前
Android 之 RxJava2
android
文火冰糖的硅基工坊7 小时前
[硬件电路-123]:模拟电路 - 信号处理电路 - 常见的高速运放芯片、典型电路、电路实施注意事项
嵌入式硬件·架构·信号处理·电路·跨学科融合