AndroidRunTime 异常 NoClassDefFoundError 在模拟器 API17 上而不是在 API22 上 [英] AndroidRunTime exception NoClassDefFoundError on simulator API17 but not on API22

查看:31
本文介绍了AndroidRunTime 异常 NoClassDefFoundError 在模拟器 API17 上而不是在 API22 上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Android Studio:1.3.1 - Gradle 构建插件:1.1.2 - Gradle:1.3.0

Android Studio: 1.3.1 - Gradle Build Plugin: 1.1.2 - Gradle: 1.3.0

在 Android Studio 上,我有一个应用程序可以在 Android API22(棒棒糖,在模拟器 API22 和 Android 手机 API22 上运行,也可以在 API 21 上运行 - 但没有低于 API 21).

On Android Studio, I have an app that runs perfectly fine on Android API22 (Lollipop, on both simulator API22 and Android phone API22, and also works on API 21 - but nothing below API 21).

在我的 Gradle 构建文件中,我有以下内容:

In my Gradle build file, I have the following:

compileSdkVersion 22
buildToolsVersion "22.0.1"

defaultConfig {
    minSdkVersion 17
    targetSdkVersion 22
...
compile "commons-io:commons-io:2.4" //IO

所以,据我所知:我的应用程序是使用最新的 API (22) 编译的,可以在从 API 17 到 API 22(以及 22+ 兼容模式)的设备上运行.

So, as I understand it: my app is compiled with the latest API (22) to run on devices from API 17 to API 22 (and 22+ in compatibility mode).

但是,当我在 API 17 模拟器上运行 Android 应用程序时,它在某些文件复制操作期间崩溃.在崩溃之前,dalivkvm 抱怨它找不到方法.

However, when I run the Android app on a API 17 simulator, it crashes during some file copy operations. Before the crash, dalivkvm complains it cannot find methods.

I/dalvikvm﹕ Could not find method org.apache.commons.io.FileUtils.copyInputStreamToFile, 
referenced from method FileCopy.batchCreate
W/dalvikvm﹕ VFY: unable to resolve static method 58205: Lorg/apache/commons/io/FileUtils;
.copyInputStreamToFile (Ljava/io/InputStream;Ljava/io/File;)V
D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x0058

然后是致命的异常:

E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NoClassDefFoundError: org.apache.commons.io.FileUtils

现在显然可以存在和导入 apache 公共库,至少在 API 22 上(我提醒您,它可以在设备和模拟器上成功运行).

Now obviously the apache commons libraries can be present and imported, at least on API 22 (which, I remind you, runs successfully on both the device and the simulator).

除了 Apache Commons 之外的其他库也会发生这种情况(如果我跳过使用 Apache Commons,那么另一个第三方库会导致类似的问题等等).

This also happens for other libraries aside from the Apache commons one (if I skip using the Apache Commons, then another third party library will cause a similar issue and so on).

我不知道为什么它不能在 API 17 上运行.在 API 18 和 19 上也有同样的问题,API 20 不存在.

I'm at loss as to why it won't run on API 17. Also have the same issues on API 18 and 19, API 20 doesn't exist.

它似乎在 API 21 和 API 22 上都能正常工作.

It appears to work correctly on both API 21 and API 22.

我在这里寻找过类似的错误,但通常是因为人们只是忘记包含他们的 jar 库,所以它没有帮助.

I've looked for similar errors on here, but usually it is because people simply forgot to include their jar libs so it didn't help.


更新

  • MultiDex is enabled. On API 21 (Lollipop) the way multidex is supported has changed (see https://developer.android.com/tools/building/multidex.html). So it might have something to do with this.

当应用程序处于调试模式"时,Gradle 以发布模式"构建模块 (当应用程序处于调试状态时,为什么 Gradle 在发布模式下构建我的模块)

Gradle builds Modules in "release mode" when app is in "Debug mode" (Why does Gradle build my module in Release mode when the app is in Debug)

我尝试重建,用文件创建一个新项目但无济于事.

I tried rebuilding, creating a new project with the files to no avail.

commons-io:commons-io:xxx"文件夹位于 Gradle 缓存文件夹中.

The "commons-io:commons-io:xxx" folder is present in the Gradle cache folder.

推荐答案

我能够解决我自己的问题.

I was able to fix my own issue.

基本上,据我所知(但我没有时间进一步调查),问题是由于 Android API 21(又名 Android 5.0)支持Multidex"的方式发生了变化.

So essentially, as I understand it (but I don't have time to investigate further), the issue is due to the fact that the way "Multidex" is supported has changed in Android API 21 (aka Android 5.0).

链接:https://developer.android.com/tools/building/multidex.html 告诉我们:

Android 5.0 及更高版本使用称为 ART 的运行时支持从应用程序 APK 文件中加载多个 dex 文件.

Android 5.0 and higher uses a runtime called ART which natively supports loading multiple dex files from application APK files.

现在,似乎当在同一应用程序中进行多索引并尝试同时支持普通 DEXing"(5.0/API21 之前)和ART oat 文件"(5.0/API21 之后的新DEX"文件)时,您可以遇到一些与我类似的问题(无法找到 API21 之前的一些方法,但应用程序在 API21 及更高版本上运行良好).

Now, it would seem that when multidexing and trying to support both "normal DEXing" (before 5.0/API21) and "ART oat files" (the new "DEX" files after 5.0/API21) in the same application you can encounter some issues similar to mine (unable to find some methods before API21 but app working fine on API21 and above).

我的应用达到了 65k 方法的限制,我不得不支持 API17+.

My app hit the 65k methods limit and I had to support from API17+.

无论如何,解决方法是禁用 multidex 并使用带有Proguard"的 minifyEnabled 代替,以便 Proguard 删除所有未使用的方法,并且方法总数最终低于 65k.

Anyway, the workaround was to disable multidex and use instead minifyEnabled with "Proguard", so that all unused methods are removed by Proguard and the total number of methods ends up below 65k.

相关代码(在 Gradle 构建文件中):

The associated code (in Gradle build file):

defaultConfig {

    ...

    //Enabling multidex support (for more than 65k methods)
    multiDexEnabled false
}

buildTypes {
    debug {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

这当然不是真正的解决方案,因为需要有效使用 65k 方法的人必须使用 multidex,但它对我来说做得很好,我不能在这些问题上花更多时间.

This isn't a real solution, of course, as someone who needs to effectively use 65k methods will HAVE to use multidex, but it did the job nicely for me and I can't spend more time on these issues.

希望这会对某人有所帮助.

Hopefully this will help someone.

这篇关于AndroidRunTime 异常 NoClassDefFoundError 在模拟器 API17 上而不是在 API22 上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆