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
相关产品推荐
相关产品推荐

