使用 kotlin 自定义风格的 ClassNotFoundException

Posted

技术标签:

【中文标题】使用 kotlin 自定义风格的 ClassNotFoundException【英文标题】:ClassNotFoundException in custom flavor using kotlin 【发布时间】:2014-12-31 04:28:32 【问题描述】:

我定义了自己的风格并设置了 sourceSet:

sourceSets     
    main.java.srcDirs += 'src/main/kotlin'           // WORKS
    myflavor.java.srcDirs += 'src/myflavor/kotlin'   // DOESN'T WORK

这是我的项目结构:

但是...我收到以下错误:

java.lang.RuntimeException: Unable to instantiate activity ComponentInfoxyz/xyz.MainActivity: java.lang.ClassNotFoundException: Didn't find class "xyz.MainActivity" on path: DexPathList[[zip file "/data/app/xyz/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
        at android.app.ActivityThread.access$800(ActivityThread.java:144)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "xyz.MainActivity" on path: DexPathList[[zip file "/data/app/xyz/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
        at android.app.ActivityThread.access$800(ActivityThread.java:144)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Suppressed: java.lang.ClassNotFoundException: xyz.MainActivity
        at java.lang.Class.classForName(Native Method)
        at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
        at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
        ... 13 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

但是,使用 main sourceSet 可以... 我会很感激你的帮助。

【问题讨论】:

【参考方案1】:

这是用于 Android 的 kotlin-gradle 插件中的一个错误,它将在 0.9.488 或更高版本中修复。

【讨论】:

我们已经修复了它,所以你可以简单地使用快照 kotlin 插件。 我在 kotlin-gradle 0.12.1230 中看到此错误,不知道如何修复.. 我尝试了 Jayson 的回答,将我的 /src/debug 文件夹添加到 main.java.srcDirs 或调试.java.srcDirs 但它没有影响任何东西。另外,我在 /src/debug 中只有一个 res 文件夹,没有 Kotlin 文件,所以我不明白它为什么会有所作为。 非 Android 用户请注意,Intellij 16 EAP 添加了对现在与 Gradle 模型一致的多个源集的支持,这全面修复了与 Gradle 相关的大多数此类问题。 插件版本 1.0.5 上仍然出现 classnotfoundexception【参考方案2】:

就我而言,我在 gradle 文件中忘记了 apply plugin: 'kotlin-android'。虽然我的项目构建成功,但它在运行时抛出java.lang.ClassNotFoundException。我正在使用 Kotlin 1.1.1

【讨论】:

如果我在应用程序build.gradle 文件中添加以下行:apply plugin: "kotlin-android",我可以启动到 MainActivityKotlin.kt。没有这条线,我会得到同样的错误。请注意,Android Studio 中的“为项目配置 Kotlin”操作会在*** build.gradle 文件中添加一个 kotlin 插件,其中包含以下行:apply plugin: 'kotlin'。在撰写本文时,Kotlin 版本级别也是 1.1.1。【参考方案3】:

尝试将两者都添加到 main.java.srcDirs,因为您希望它们都编译是吗?

sourceSets     
    main.java.srcDirs += 'src/main/kotlin'         
    main.java.srcDirs += 'src/myflavor/kotlin'   

【讨论】:

谢谢,已尝试但效果不佳。我想编译 myflavor/kotlin、myflavor2/kotlin、myflavor3/kotlin 来分离 apk 文件,其中 main/kotlin 有每个 apk 的核心源代码。 而且这些不能是单独的模块(Gradle 子项目)? 这实际上不是我想要实现的——我需要具有指定包和来源的独立风味,但正如 Natalia 所写的那样——这是一个错误,所以现在我正在等待修复。跨度> 非 Android 用户请注意,Intellij 16 EAP 添加了对现在与 Gradle 模型一致的多个源集的支持,这全面修复了与 Gradle 相关的大多数此类问题。【参考方案4】:

当我将源代码转换为 kotlin 时,我也遇到了错误。我的解决方法是更改​​ gradle 中的 sourceSets。

之前

sourceSets      
    main.java.srcDirs += 'src/main/kotlin'

现在

sourceSets      
    main.java.srcDirs += 'src/main/java'

【讨论】:

这个答案解决了我的问题。但我发现 .kt 文件与其他 .java 文件并排放置。所以将main.java.srcDirssrc/main/kotlin 更改为src/main/java 确实有意义。【参考方案5】:

我可以确认,至少在 Kotlin 插件版本 1.1.1 和 1.1.2 中,该错误已得到修复,您可以使用 kotlin 文件夹(推荐而不是 java 文件夹) 有不同的口味:

sourceSets 
    androidTest 
        java.srcDir file('src/androidTest')
    
    test.java.srcDirs += 'src/test/kotlin'
    main.java.srcDirs += 'src/main/kotlin'
    flavor1.java.srcDirs += 'src/flavor1/kotlin'
    flavor2.java.srcDirs += 'src/flavor2/kotlin'

【讨论】:

【参考方案6】:

我遇到了同样的问题。就我而言,我正在构建一个库和一个用于访问该库的测试应用程序。

当我将项目转换为 kotlin 时,它会将相关的 kotlin 依赖项添加到库的 gradle 文件中,而不是主应用程序。

确保所有相关的 gradle 文件中包含以下行:

apply plugin: "kotlin-android"

dependencies 
...
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
...

【讨论】:

以上是关于使用 kotlin 自定义风格的 ClassNotFoundException的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 中的自定义数字键盘

Kotlin 2路绑定自定义视图

浅谈Kotlin:类

在kotlin中使用java自定义注释

Android面试Kotlin高阶之必问三连

在 Kotlin 中使用自定义 JsonDeserializer 进行改造