在一些场景下,使用 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
maven("https://s01.oss.sonatype.org/content/repositories/snapshots")
implementation("xyz.junerver.compose:hooks2:2.1.0-alpha0-SNAPSHOT")