gpt4 book ai didi

android - 与 Android 和桌面项目共享 Kotlin 模块

转载 作者:行者123 更新时间:2023-11-30 00:32:14 25 4
gpt4 key购买 nike

我正在开发一款使用 LibGDX 游戏框架的游戏。目前,我的目标平台是桌面(PC、Mac、Linux)(通过独立于平台的 jar 和 Android)。

项目托管于https://github.com/NoxHarmonium/project-whiplash如果需要,请随时查看。

大部分代码位于名为 core 的模块中,并且完全用 Kotlin 编写。此模块链接到桌面和 Android 项目。

这适用于 Android 版本 7.1+ 和桌面。对于所有其他版本的 Android,我得到一堆关于匿名函数的 java.lang.NoClassDefFoundError 异常,例如:

val objectObservable = this.observableCache.computeIfAbsent(assetRef, fun(assetRef: AssetRef): Observable<T> {
return Async.start(fun(): T {
...
}).observeOn(this.eventLoopScheduler)
})

异常示例:

java.lang.NoClassDefFoundError: com.projectwhiplash.utils.assets.LibGdxDataManager$objectMapFromYaml$objectMapObservable$1

这似乎是由于与 Kotlin 默认目标的 JVM (1.8) 和旧版本的 Android 支持的 JVM 级别 (1.6) 不兼容造成的。我可能是错的,但这解释了为什么最新版本的 Android 可以工作,因为它支持更高版本的 JVM。

解决方案应该像强制 Kotlin 发出 1.6 版本的 JVM 字节码一样简单,但我似乎无法解决。如果您将 Kotlin 直接编译成 Android,这似乎可以通过使用 kotlin-android Gradle 插件来处理。不幸的是,我不能将这个插件用于核心模块,因为它不应该有任何 Android 依赖项。

我尝试使用 https://kotlinlang.org/docs/reference/using-gradle.html#compiler-options 中提到的build设置覆盖 JVM 版本像这样:

编译Kotlin {
kotlin选项{
jvmTarget = "1.6"
}
}

但是,无论我将它放在哪个 Gradle 文件中,它似乎都不起作用。事实上,当我尝试它时,我收到了 Intellij 显示的“无法解析符号‘kotlinOptions’”错误。可能是 Kotlin 团队更改了某些内容而文档尚未更新。

我可以在 Intellij 模块设置中手动覆盖 Kotlin 设置,但每次同步 gradle 项目时它都会被覆盖,这不是一个好的长期解决方案。该项目旨在独立于 IDE。

有谁知道如何设置核心模块以最大程度地兼容旧版 Android?

我目前将最低 API 级别设置为 9,因为这是当前 LibGDX 的默认设置,但如果很难以如此低的 API 级别为目标,我愿意将其设置得更高。

编辑 1:

我刚刚提取了核心模块生成的 jar 文件,并使用 javap 工具检查了类文件。

我在一个随机类文件上运行了以下命令

java -verbose foo.class

它输出带有以下文本的文本


...
次要版本:0
主要版本:50
...

使用这个问题 List of Java class file format major version numbers?我确定该类文件实际上是针对 JVM 1.6。

因此我原来的理论是错误的,还有另一个原因导致旧的 Android 版本无法加载由 Kotlin lambda 生成的类。

最佳答案

看起来您正在使用仅存在于 JDK 8 库中的功能。特别是 Map 类上的 computeIfAbsent() 方法。

因此,即使您的代码已被编译为与 JVM 1.6 兼容,Android 设备上的底层实现仍缺少该功能,这也是您看到的 NoClassDefFoundError 异常的原因。

更新:您可以在位于 https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function- 的 javadoc 中看到computeIfAbsent() 自 JDK 8 以来才存在

关于android - 与 Android 和桌面项目共享 Kotlin 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44096156/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com