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

Kotlin Multiplatform项目结构、图片显示及SharedPreferences实现问题

Kotlin Multiplatform项目问题解答

1. 项目结构合理性确认

你的项目结构整体符合JetBrains官方KMM项目规范,不过有几个可优化的细节:

  • jvmAndAndroidMain源集的使用逻辑没问题,但要确保common模块的build.gradle.kts中正确配置该源集的依赖,避免重复引入依赖包。
  • 安卓端MainActivity仅负责启动Compose内容的设计是合理的,符合KMM跨平台UI的分工原则。
  • 注意common/src/commonMain/resources作为资源根目录,安卓端需要在common模块的Gradle配置中添加资源复制逻辑,否则安卓系统无法识别这些资源(这也是你第二个问题的核心诱因)。

2. 跨平台图片加载问题

桌面端可直接通过路径加载commonMain内的图片,但安卓端资源系统基于编译生成的R类ID运行,无法直接识别路径,且commonMain的资源不会自动生成安卓的R文件,因此报错。推荐两种解决方案:

方案一:用expect/actual封装图片加载

在commonMain的Platform.kt中定义预期函数:

expect fun getImagePainter(imgName: String): Painter

在androidMain的Platform.kt中实现安卓端逻辑:

actual fun getImagePainter(imgName: String): Painter {
    val resId = when(imgName) {
        "a" -> R.drawable.a
        "b" -> R.drawable.b
        "c" -> R.drawable.c
        else -> throw IllegalArgumentException("Unknown image: $imgName")
    }
    return painterResource(resId)
}

在desktopMain的Platform.kt中实现桌面端逻辑:

actual fun getImagePainter(imgName: String): Painter {
    return painterResource("drawable/${imgName}.png")
}

之后在Application.kt中调用getImagePainter(imgName)即可实现跨平台图片加载。

方案二:同步common资源到安卓端

在common模块的build.gradle.kts中添加Gradle任务,将commonMain/resources/drawable下的图片自动复制到安卓模块的src/main/res/drawable目录,这样安卓端就能通过R.drawable访问,同时保持资源的统一性。

3. 安卓端SharedPreferences获取Context避免循环依赖

通过MainActivity伴生对象获取Context会导致循环依赖(安卓模块依赖common模块,而common又引用安卓模块的MainActivity),正确做法是使用Application级别的Context:

  1. 在安卓模块中创建自定义Application类:
class MyApp : Application() {
    companion object {
        lateinit var context: Context
            private set
    }

    override fun onCreate() {
        super.onCreate()
        context = applicationContext
    }
}
  1. 在AndroidManifest.xml中注册该Application:
<application
    android:name=".MyApp"
    ...>
    ...
</application>
  1. 在common/src/androidMain/Platform.kt中直接使用MyApp.context获取上下文:
val sharedPreferences = MyApp.context.getSharedPreferences("app_data", Context.MODE_PRIVATE)

这种方式不会产生循环依赖,因为安卓模块依赖common模块,common的androidMain源集可正常访问安卓模块的类。

内容的提问来源于stack exchange,提问作者Aditya Verma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:07:47