【Jetpack Compose进阶学与练】第20课 KMP Compose‑Multiplatform基础;一套UI跨Android、桌面
前言
前面1‑19课学习的是Android平台原生Jetpack Compose,只能运行在安卓手机。
Compose‑Multiplatform(C‑MP)基于KMP(Kotlin Multiplatform),同一套Compose UI代码,可以编译运行Android、Windows/macOS/Linux桌面,iOS(尚处于逐步完善)。
本节课区分原生Jetpack‑Compose 和 Compose‑Multiplatform;基础工程结构;共享模块;简单HelloWorld。
知识点清单
- Jetpack Compose(Android专属) vs Compose‑Multiplatform(KMP跨平台)
- KMP工程结构:shared共享模块 + 各平台独立模块(android、desktop)
- expect‑actual 声明‑实际,用来处理平台特定代码
- 共享模块编写跨平台UI;桌面入口main函数;Android的Activity入口
- 简单HelloWorld示例
环境前置
IDE:Android Studio(安装KMP插件);JDK17;Gradle版本尽量新。
完整示例源码
/**
* shared 共享模块‑跨平台UI代码(android、desktop都复用这部分)
*/
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@Composable
fun SharedMainScreen() {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Compose‑Multiplatform 跨平台演示!")
Button(onClick = {}) {
Text("通用按钮")
}
}
}
/**
* desktop桌面端入口,独立main函数,没有Activity
*/
fun main() {
androidx.compose.ui.window.application {
androidx.compose.ui.window.Window(onCloseRequest = ::exitApplication) {
SharedMainScreen()
}
}
}
/**
* Android端入口 Activity(android模块)
*/
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
class AndroidMainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SharedMainScreen()
}
}
}
/**
* expect‑actual平台差异化代码示例
*/
expect fun getPlatformName(): String
//android实现(android源集)
actual fun getPlatformName(): String {
return "Android"
}
//desktop实现(desktop源集)
actual fun getPlatformName(): String {
return "Desktop"
}
逐行解读
- Jetpack‑Compose VS Compose‑Multiplatform
- Jetpack Compose:Android专属,只能跑安卓手机;依赖Android Framework;API由Google Android团队维护。
- Compose‑Multiplatform:KMP跨平台;UI渲染层独立;一套Compose声明式UI;编译输出Android App、桌面exe/dmg;iOS还在持续完善;
⚠️注意:不是写一次就所有平台完全适配!依然会存在平台差异,平台特定逻辑需要expect‑actual。
- 工程模块结构
- shared :共享模块,存放大部分Compose UI、业务逻辑;这部分代码会被Android模块和Desktop模块同时引用;
- androidApp :安卓应用模块;只保留Activity,直接复用shared里面的@Composable页面;
- desktopApp :桌面应用模块;入口是普通fun main(),没有Activity,没有Android生命周期;使用Window创建应用窗口。
- expect‑actual(声明‑实际)
当业务需要调用平台独有的能力:比如读取Android权限;Windows读取本地文件;iOS通知;
先在shared的common源集写 expect fun xxx() 做抽象声明;
然后分别在android、desktop源集编写 actual fun xxx() 提供对应平台的实现。
common共享代码就可以调用这个函数;编译期会自动链接对应平台的实现。
expect‑actual是KMP解决平台差异化的核心机制。
- 桌面端入口 application{}与Window{}
桌面端没有Activity; application {} 代表整个桌面应用程序; Window{} 代表一个窗口;可以打开多个窗口; exitApplication() 关闭整个程序。 - 资源处理痛点
图片、字符串资源:C‑MP现在有统一资源方案;旧项目经常需要分别维护各平台资源;新项目优先使用新版gradle的KMP资源管理。
容易踩坑
- ❌误以为KMP写一套代码之后所有平台不用做任何适配;UI控件行为、系统权限、文件路径各个平台都不一样;平台相关逻辑仍然要用expect‑actual隔离。
- ❌ 在common共享代码里面直接调用Android SDK(Context、Toast);common源集看不到Android框架API,编译报错;必须抽象之后交给平台层actual实现。
- ❌ 直接把原生Android Jetpack Compose项目简单改一改就当成C‑MP;工程需要重新搭建KMP模块结构。
- ❌ 桌面端照搬Android的Activity生命周期;桌面没有Activity,窗口生命周期自己管理。
- ✅ shared模块放通用UI;androidApp、desktopApp作为外壳;expect‑actual隔离平台独有逻辑;桌面入口main+application+Window。
多元化习题(练习)
习题1【基础‑改错题】
直接在KMP的common共享代码里面调用Android的Toast,为什么编译报错?
答案:
common共享源集不依赖Android SDK;看不到Android平台API;不能直接调用;需要用expect声明接口,Android模块使用actual完成平台实现。
解读:
共享层只写跨平台通用逻辑;平台能力通过expect‑actual向外抽象。
习题2【基础‑代码修改题】
common里面声明一个获取操作系统版本名称的expect函数(只写expect声明)
答案:
expect fun getOsVersionName(): String
解读:
之后分别在android、desktop源集编写actual实现。
习题3【进阶‑补充代码题】
desktop端Compose‑Multiplatform如何关闭整个桌面应用?
答案:
调用 exitApplication() ;该函数需要放在application作用域内;一般写在窗口关闭回调onCloseRequest。
解读:
桌面没有finish();使用exitApplication退出进程。
习题4【综合‑逻辑应用题】
KMP Compose‑Multiplatform项目为什么要拆分成shared共享模块 + androidApp、desktopApp外壳模块?
答案:
UI与业务尽量全部放在shared,实现最大程度复用;androidApp与desktopApp仅仅作为各平台薄薄的外壳,负责提供平台入口、平台特定实现;后续新增iOS目标时,只需要新增一层外壳模块,尽量不用修改shared业务代码。
解读:
分离通用业务与平台外壳是KMP工程的核心思想。
习题5【概念简答题】
Jetpack Compose(Android原生)与Compose‑Multiplatform最核心区别是什么?
答案:
Jetpack Compose深度绑定Android系统框架,仅支持Android;
Compose‑Multiplatform基于KMP,渲染引擎独立;同一套Compose UI可以编译到Android、桌面,正在完善iOS;但各平台系统能力依然需要expect‑actual做适配。
解读:
二者的Compose语法几乎一样;底层渲染和平台绑定程度不一样。
本节课知识点总结
- Jetpack Compose是Android专属;Compose‑Multiplatform(KMP)实现跨Android、桌面,iOS持续演进;二者UI语法基本一致。
- KMP推荐工程架构:shared共享模块存放UI业务;androidApp与desktopApp作为平台外壳;Android依靠Activity;桌面以main函数、application+Window作为程序入口。
- expect‑actual声明‑实际机制,用来隔离平台差异化API;common层只做抽象;各平台源集完成具体实现。
- 不要幻想完全零适配跨平台;系统权限、文件、弹窗依然存在平台差异,必须针对性处理。
- 新版KMP已经支持统一资源管理,新项目优先采用新版资源方案,减少多平台资源维护负担。
📌到此【Jetpack Compose基础语法学与练】全套20课完结。
更多推荐



所有评论(0)