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

KMP项目主/测试目标跨平台共享资源配置方案咨询

KMP双端资源加载与测试方案

一、主代码(commonMain)加载外部JSON文件

1. Gradle配置资源路径

在core模块的build.gradle.kts中,将根目录dependencies/data下的JSON文件配置为各平台可访问资源:

  • Android端:
android {
    sourceSets {
        main {
            resources.srcDir("../../dependencies/data")
        }
    }
}
  • iOS端(针对所有iOS架构目标):
iosX64 {
    binaries.framework {
        baseName = "Core"
        resources.srcDir("../../dependencies/data")
    }
}
iosArm64 {
    binaries.framework {
        baseName = "Core"
        resources.srcDir("../../dependencies/data")
    }
}

2. 跨平台资源读取实现

利用expect/actual机制封装资源读取逻辑:

  • commonMain中定义抽象函数:
expect fun loadJsonFromAsset(fileName: String): String
  • androidMain中实现:
actual fun loadJsonFromAsset(fileName: String): String {
    // 建议通过依赖注入获取Application Context,避免全局单例泄漏
    return appContext.assets.open(fileName).bufferedReader().use { it.readText() }
}
  • iosMain中实现:
actual fun loadJsonFromAsset(fileName: String): String {
    val bundle = NSBundle.bundleForClass(MyData::class.java)
    val path = bundle.pathForResource(fileName, "json") ?: error("JSON文件未找到")
    return NSString.stringWithContentsOfFile(path, encoding = NSUTF8StringEncoding, error = null) as String
}

3. JSON解析生成Kotlin实例

以Kotlinx Serialization为例,在commonMain中完成解析:

@Serializable
data class MyData(val id: Int, val name: String)

private val jsonParser = Json { ignoreUnknownKeys = true }

fun parseJson(jsonContent: String): MyData {
    return jsonParser.decodeFromString(jsonContent)
}

// 调用示例
val data = parseJson(loadJsonFromAsset("data.json"))

二、commonTest中JSON解析验证测试

1. 配置测试资源目录

在core模块下创建src/commonTest/resources存放测试专属JSON,同时在build.gradle.kts中配置:

sourceSets {
    commonTest {
        resources.srcDir("src/commonTest/resources")
    }
    // Android测试同步资源
    androidTest {
        resources.srcDir("src/commonTest/resources")
    }
}

iOS测试端无需额外配置,Gradle会自动将测试资源打包进测试框架。

2. 测试资源读取实现

同样用expect/actual封装测试资源读取:

  • commonTest中定义:
expect fun loadTestJson(fileName: String): String
  • androidTest中实现:
actual fun loadTestJson(fileName: String): String {
    return ClassLoader.getSystemResourceAsStream(fileName).bufferedReader().use { it.readText() }
}
  • iosTest中实现:
actual fun loadTestJson(fileName: String): String {
    val bundle = NSBundle.bundleForClass(JsonParsingTest::class.java)
    val path = bundle.pathForResource(fileName, "json") ?: error("测试JSON未找到")
    return NSString.stringWithContentsOfFile(path, encoding = NSUTF8StringEncoding, error = null) as String
}

3. 编写测试用例

在commonTest中编写跨平台验证测试:

import kotlin.test.Test
import kotlin.test.assertEquals

class JsonParsingTest {
    @Test
    fun `解析测试JSON数据正确`() {
        val testJson = loadTestJson("test_data.json")
        val parsedData = parseJson(testJson)
        assertEquals(1001, parsedData.id)
        assertEquals("测试名称", parsedData.name)
    }
}

三、关键注意事项

  • 确认Gradle中的相对路径正确,建议从core模块根目录向上回溯到dependencies/data
  • Android主代码的Context优先用依赖注入(如Koin)提供,避免全局静态实例引发内存泄漏
  • iOS端主代码中,需用框架自身的Bundle而非NSBundle.mainBundle,避免资源找不到的问题
  • 测试资源必须放在commonTest/resources目录下,确保双端测试均可访问

内容的提问来源于stack exchange,提问作者José González

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 08:55:05