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

KMM中使用OKIO访问commonMain资源文件的路径配置问题

解决KMP中Android端读取commonMain资源文件的问题

问题根源

Android平台打包后,src/commonMain/resources下的文件会被放到APK的assets目录中,而非保留原本地路径。你直接用FileSystem.SYSTEM读取src/resources/initialdata.json这种本地路径,自然会找不到文件。

正确实现方案

1. 修正expect/actual定义(支持协程)

在commonMain中定义带协程的接口:

expect class FileResourceParser {
    suspend fun parseInitialFile(): String
}

2. Android端实际实现

通过Context访问Assets目录读取文件,支持原生流或OKIO两种方式:

actual class FileResourceParser(private val context: Context) {
    actual suspend fun parseInitialFile(): String {
        // 原生流方式
        return context.assets.open("initialdata.json").use { inputStream ->
            inputStream.readBytes().decodeToString()
        }
        
        // 或用OKIO方式
        // return Okio.buffer(Okio.source(context.assets.open("initialdata.json"))).readUtf8()
    }
}

3. iOS端实际实现

通过App Bundle获取资源路径,再用OKIO读取:

actual class FileResourceParser {
    actual suspend fun parseInitialFile(): String {
        val filePath = NSBundle.mainBundle.pathForResource("initialdata.json", null)
            ?: error("initialdata.json 未在Bundle中找到")
        return FileSystem.SYSTEM.read(filePath.toPath()) { readUtf8() }
    }
}

4. 修正Realm初始化代码

Realm的initialData是同步执行的,需要用runBlocking包裹协程调用,同时区分平台传入Context(Android):

val config = RealmConfiguration.Builder(schema = schema)
    .name("boardDb-local")
    .initialData {
        val jsonString = runBlocking {
            val parser = if (Platform.isAndroid) {
                // 替换为你的ApplicationContext
                FileResourceParser(applicationContext)
            } else {
                FileResourceParser()
            }
            parser.parseInitialFile()
        }
        val exerciseList: List<Exercise> = Json.decodeFromString(jsonString)
        // 直接循环写入Realm,无需转RealmList
        exerciseList.forEach { copyToRealm(it, UpdatePolicy.ALL) }
    }
    .log(LogLevel.ALL)
    .schemaVersion(1)
    .build()

额外注意事项

  • 确保initialdata.json确实放在src/commonMain/resources目录下,文件名大小写完全匹配(Android对文件名大小写敏感)
  • Android端获取ApplicationContext时,避免内存泄漏,建议用Application级别的Context
  • 若不需要协程,也可以将读取逻辑改为同步,但IO操作尽量放在后台线程执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 05:16:05