编译 Kotlin 文件到 Dex 产生 ClassNotFoundException (kotlin.jvm.internal.Intrinsics)

Compiling Kotlin file to Dex generates ClassNotFoundException (kotlin.jvm.internal.Intrinsics)

我正在尝试在我的 Android 设备上为 运行 创建一个命令行脚本。我正在使用 Dalvik VM 跟踪这个 answer 到 运行 编译的 kotlin 文件,但是当我在 adb 运行 dalvikvm -cp TestKt.zip 上 shell:

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,所以我不确定这是否正确方法。

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

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

默认情况下,kotlin 编译器已经生成了针对 JRE6 的 Java 字节码,这是 Dalvik 所需要的 运行,因此只需将 kotlin 运行time 包含在其中即可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用于删除Java8个特征。由于 kotlin 编译器默认以 JRE6 为目标,因此不需要脱糖。

一些对我有帮助的链接:

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