【问题标题】:Compiling Kotlin file to Dex generates ClassNotFoundException (kotlin.jvm.internal.Intrinsics)将 Kotlin 文件编译为 Dex 生成 ClassNotFoundException (kotlin.jvm.internal.Intrinsics)
【发布时间】:2019-08-29 21:56:35
【问题描述】:

我正在尝试创建一个命令行脚本以在我的 Android 设备上运行。我正在关注answer 以使用 Dalvik VM 运行已编译的 kotlin 文件,但是当我在 adb shell 上运行 dalvikvm -cp TestKt.zip 时出现以下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
    at TestKt.main(Unknown Source:2)
Caused by: java.lang.ClassNotFoundException: Didn't find class
"kotlin.jvm.internal.Intrinsics" on path: DexPathList[[zip file "TestKt.zip"],
nativeLibraryDirectories=[/system/lib64, /system/vendor/lib64, 
/system/lib64, /system/vendor/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    ... 1 more

这是我正在尝试编译的简单文件 (Test.kt):

package edu.ufrn.lapps

fun main(args: Array<String>) {
    println(args.size);
}

我写了一个 Makefile 来编译它(主要是因为这只是一个测试,但是一旦我需要依赖项,我可能会转移到 Gradle):

NAME := TestKt
OUTPUT := TestKt

PKG := edu/ufrn/lapps
KFLAGS := -include-runtime

D8C := $(HOME)/Android/Sdk/build-tools/29.0.1/d8
D8FLAGS := --no-desugaring 

dex:
    kotlinc src/$(PKG)/Test.kt
    $(D8C) $(D8FLAGS) $(PKG)/$(OUTPUT).class

zip: dex 
    zip $(OUTPUT).zip classes.dex

jvm:
    kotlinc $(SRC)/Test.kt $(KFLAGS) -d $(OUTPUT).jar

.PHONY: clean

clean:
    -rm -r META-INF/
    -rm $(OUTPUT).jar $(OUTPUT).zip

我正在尝试按照AOSP cmds 制作我的 CLI 脚本,但我之前从未将 Java 字节码编译为 Dex,所以我不确定这是否是正确的方法。

我应该如何解决这个错误?

【问题讨论】:

  • 我认为你在正确的轨道上,但看起来你需要弄清楚如何在 dex 文件中包含 kotlin 框架。我不知道它是如何正常工作的,所以我无法提供具体的帮助。
  • 哦,我以为 kotlin 编译器是为我做的。我会更深入地研究它。如果是这样的话,我想我会更幸运地使用 gradle 为我自动化构建过程。

标签: android kotlin dalvik


【解决方案1】:

我设法将 Kotlin 源文件编译成可接受的 Dex 文件。 JesusFreke 的提示确实有帮助,并且是问题的根源。

默认情况下,kotlin 编译器已经生成了针对 JRE6 的 Java 字节码,这是 Dalvik 需要运行的,因此只需将 kotlin 运行时包含到 Dex 文件中即可。

这是我所做的:

$ kotlinc src/edu/ufrn/lapps/Test.kt -include-runtime -d TestKt.jar 
$ ~/sdk-patk/build-tools/29.0.1/d8 TestKt.jar --no-desugaring
$ zip TestKt.zip classes.dex
$ adb push TestKt.zip /sdcard/
$ adb shell
$ [on adb shell]: dalvikvm -cp /sdcard/TestKt.zip edu.ufrn.lapps.TestKt

根据d8 compiler 文档,--no-desugaring 用于删除 Java 8 功能。由于 kotlin 编译器默认以 JRE6 为目标,因此不需要脱糖。

一些对我有帮助的链接:

【讨论】:

    【解决方案2】:

    从输出文件夹中删除调试 Apk 文件解决了它 在这个路径 app/build/outputs/apk/debug/myapp.apk

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-16
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多