如何在JVM与Android等多平台目标间复用函数?
解决Kotlin跨平台JVM/Android代码复用问题
针对你遇到的JVM和Android平台需重复实现同一expect函数的问题,有几种实用方案可以避免代码复制:
1. 配置共享源集(推荐)
Kotlin Multiplatform支持自定义共享源集,将JVM和Android通用的代码放在同一目录下,让两个平台的源集都依赖它,实现一次编写多平台复用。
步骤1:修改Gradle配置
在模块的build.gradle.kts中添加自定义共享源集:
kotlin { sourceSets { // 创建JVM和Android共享的源集 val jvmAndAndroidMain by creating { dependsOn(commonMain.get()) kotlin.srcDir("src/jvmAndAndroidMain/kotlin") } // 让JVM和Android主源集依赖共享源集 jvmMain.get().dependsOn(jvmAndAndroidMain) androidMain.get().dependsOn(jvmAndAndroidMain) } }
步骤2:在共享源集中实现actual函数
在项目目录下创建src/jvmAndAndroidMain/kotlin目录,放入平台共用的实现:
actual fun defaultFormatterWeekDayLabel(dayOfWeek: DayOfWeek): String { return dayOfWeek.getDisplayName( TextStyle.SHORT, Locale.getDefault() ) }
这样JVM和Android平台会自动使用这个共享实现,无需在各自源集里重复编写。
2. Android直接复用JVM端实现
如果不想修改源集结构,可以让Android平台的actual函数直接调用JVM端的实现,前提是代码在Android和JVM上兼容(你的场景完全满足)。
JVM端实现(src/jvmMain/kotlin)
actual fun defaultFormatterWeekDayLabel(dayOfWeek: DayOfWeek): String { return dayOfWeek.getDisplayName( TextStyle.SHORT, Locale.getDefault() ) }
Android端实现(src/androidMain/kotlin)
// 直接调用JVM端的函数实现,避免重复代码 actual fun defaultFormatterWeekDayLabel(dayOfWeek: DayOfWeek): String { return your.package.name.defaultFormatterWeekDayLabel(dayOfWeek) }
注意替换your.package.name为JVM端函数所在的实际包路径。
3. 封装为共享类实现
如果后续逻辑更复杂,可以将实现封装成类,通过expect/actual让JVM和Android共用同一类实现:
Common端定义expect类(src/commonMain/kotlin)
expect class WeekDayFormatter { fun getWeekDayLabel(dayOfWeek: DayOfWeek): String }
JVM/Android共享实现(放在共享源集或JVM源集)
actual class WeekDayFormatter { actual fun getWeekDayLabel(dayOfWeek: DayOfWeek): String { return dayOfWeek.getDisplayName( TextStyle.SHORT, Locale.getDefault() ) } }
iOS端单独实现(src/iosMain/kotlin)
actual class WeekDayFormatter { actual fun getWeekDayLabel(dayOfWeek: DayOfWeek): String { return dayOfWeek.name } }
在通用代码中直接使用WeekDayFormatter类即可,无需关注平台差异。
内容的提问来源于stack exchange,提问作者prom85
相关产品推荐
相关产品推荐

