如何在 KotlinMultiplatform 项目中的target之间共享代码
在一些场景下,使用 KMP 会存在一些碎片化问题
例如同样使用 kotlin-reflect,只在 jvm、Android 下可以获得完整的反射体验。
在 ios 平台、common 平台都无法使用如下代码:
inline fun <reified T> checkCompanionObject(): Tuple3<Any, KFunction<*>, KFunction<*>> {
val companionObj = T::class.companionObjectInstance
val companionKClass = companionObj::class
val defaultMethod = companionKClass.functions.firstOrNull { it.name == "default" }
val optionOfMethod = companionKClass.functions.firstOrNull { it.name == "optionOf" }
return tuple(companionObj, defaultMethod, optionOfMethod)
}
T::class.companionObjectInstance
这个获取伴生对象的扩展属性就无法支持 ios、js 等平台。
那如果我们只想给 jvm、android 提供这个函数,将这份代码写到两个源集中无疑不方便后续的管理、修改。
我们可以在src
目录下新建一个源集目录:commonJvmAndroid
,将代码按照正确的路径放置于该源集之下
然后回到 build.gradle.kts
中进行如下修改
val commonJvmAndroid by creating {
dependsOn(commonMain.get())
} // 创建在jvm、Android中共享的源集
// 在需要共享代码的源集中依赖
androidMain.get().dependsOn(commonJvmAndroid)
val desktopMain by getting {
dependsOn(commonJvmAndroid)
}
类似的,有的 kmm 库(例如mmkv-kotlin
)只支持 ios、android,对 jvm 桌面不支持。
我们可以在 commonMain
中 通过 expect
创建相关期望函数,创建一个 commonIosAndroid
源集依赖该库,通过使用 kmm 库提供的能力进行 actual
,然后自行为 jvm 桌面平台单独实现,这样通过这个库可以覆盖的多个 target 只需要写一个 actual
即可。
写在最后
ComposeHooks 项目现已支持 CMP,可以使用快照版本进行尝鲜,工件 id 由hooks
变更为 hooks2
1 | maven("https://s01.oss.sonatype.org/content/repositories/snapshots") |