KMM共享模块使用kSoap2、java.util.Calendar报错问题咨询
问题根因
- 你将Android平台专属的依赖(安卓系统组件库、ksoap2-android、
java.util.Calendar等JVM专属API)直接放在了共享模块的commonMain依赖中,而commonMain的代码需要同时兼容Android、iOS双端运行,iOS端不存在JDK类库与安卓专属SDK,自然会抛出类型缺失、继承关系匹配失败的错误,你遇到的Kotlin.Cloneable找不到的报错,本质是iOS端没有java.util.Calendar的对应实现,类型不匹配导致。 - ksoap2-android本身就是专为安卓JVM环境开发的SOAP库,没有原生支持KMM跨平台/iOS,安卓侧能正常运行是因为环境适配,放在共享模块的通用逻辑里自然会报错。
- 共享模块依赖配置逻辑混乱,安卓专属依赖全部放在了通用依赖区,同时还在共享模块、安卓应用模块重复引入相同的jar包,额外触发了类冲突问题。
可行解决方案
1. 重构共享模块依赖结构
将所有安卓专属依赖从commonMain中移除,迁移到androidMain的依赖配置下,commonMain仅保留原生支持KMM跨平台的依赖:
sourceSets { val commonMain by getting { dependencies { // 此处仅放支持KMM跨平台的依赖,例如kotlinx系列跨平台库 implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4") } } val androidMain by getting { dependencies { // 所有安卓专属依赖全部移到此处 implementation("com.google.android.material:material:1.3.0") implementation("androidx.appcompat:appcompat:1.2.0") implementation("androidx.legacy:legacy-support-v13:1.0.0") implementation("androidx.core:core:1.0.0") implementation("androidx.legacy:legacy-support-v4:1.0.0") implementation("androidx.constraintlayout:constraintlayout:1.1.3") implementation("com.google.firebase:firebase-messaging:10.2.1") implementation("com.google.android.gms:play-services:10.2.1") implementation("com.google.android.gms:play-services-ads:10.2.1") implementation("com.google.firebase:firebase-core:10.2.1") implementation("com.google.firebase:firebase-auth:10.2.1") implementation("com.github.siyamed:android-shape-imageview:0.9.+@AndreiA") implementation("com.facebook.android:facebook-android-sdk:[5,6)") implementation("androidx.mediarouter:mediarouter:1.0.0") implementation("androidx.vectordrawable:vectordrawable:1.0.0") implementation("com.github.barteksc:android-pdf-viewer:3.1.0-beta.1") implementation("org.apache.commons:commons-io:1.3.2") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.30") // ksoap2相关jar包也移到此处 implementation(files("/Users/mbp/AndroidStudioProjects/PashtoLibrary/androidApp/libs/ksoap2-android-assembly-3.3.0-jar-with-dependencies.jar")) implementation(files("/Users/mbp/AndroidStudioProjects/PashtoLibrary/androidApp/libs/org.apache.commons.net_2.0.0.v200905272248.jar")) } } // 剩余iosMain、test相关配置保持原有逻辑即可 }
删除共享模块末尾的全局dependencies块,避免依赖作用域混乱。
2. 解决Calendar类调用报错
java.util.Calendar是JVM专属API,不能在commonMain直接调用,使用KMM的expect/actual机制封装日期工具即可:
- 先在
commonMain中定义通用接口:
expect class CalendarUtil { fun getCurrentTimeMillis(): Long // 补充其他你需要用到的日历操作方法 }
- 在
androidMain中实现安卓侧逻辑,调用原生Calendar:
import java.util.Calendar actual class CalendarUtil { actual fun getCurrentTimeMillis(): Long { return Calendar.getInstance().timeInMillis } }
- 在
iosMain中实现iOS侧逻辑,调用系统NSCalendar:
import platform.Foundation.NSCalendar import platform.Foundation.currentCalendar actual class CalendarUtil { actual fun getCurrentTimeMillis(): Long { val calendar = NSCalendar.currentCalendar return (calendar.date.timeIntervalSince1970 * 1000).toLong() } }
后续在commonMain中仅调用封装好的CalendarUtil即可,不会再出现类型缺失报错。
3. 适配ksoap2能力
ksoap2-android本身不支持iOS,按需选择方案即可:
- 如果SOAP请求逻辑仅需要在安卓侧使用,直接把这部分业务代码全部放到
androidMain目录下,不要放在commonMain中 - 如果需要双端都支持SOAP请求,更换支持KMM的跨平台SOAP库,或者基于KMM版OkHttp自行封装SOAP报文的组装、解析逻辑。
4. 清理重复依赖
安卓应用侧已经引入了shared模块,所有已经在共享模块androidMain中配置的依赖,安卓侧不需要重复引入,删除安卓应用build.gradle.kts中重复的jar包、安卓系统库依赖即可,避免类冲突。
内容的提问来源于stack exchange,提问作者hamza
相关产品推荐
相关产品推荐

