You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 01:52:39