AndroidRunTime NoClassDefFoundError exception on API17 simulator, but not on API22

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

In Android Studio, I have an application that works fine on Android API22 (Lollipop, both on the API22 simulator and on the Android22 Android phone, and also works on API 21, but nothing lower than API 21).

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 

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

However, when I run the Android application on the API 17 simulator, it crashes during some file copy operations. Before the disaster, dalivkvm complains that 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 

Then the fatal exception:

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

Now it’s obvious that apache collection libraries can be present and imported, at least on API 22 (which, I remind you, runs successfully on both the device and the simulator).

This also happens for libraries other than Apache commons one (if I skip using Apache Commons, then another third-party library will cause a similar problem, etc.).

I am losing information about why it will not work in API 17. Also there are the same problems in API 18 and 19, API 20 does not exist.

It seems to work correctly with both API 21 and API 22.

I searched for similar errors here, but usually this is because people just forgot to include their jar libs so that this does not help.


UPDATES

0
source share
1 answer

I was able to fix my own problem.

So, as far as I understand (but I don’t have time for further study), the problem is that the way to support "Multidex" has changed in Android API 21 (for example, Android 5.0).

Link: https://developer.android.com/tools/building/multidex.html tells us:

Android 5.0 and above uses a runtime called ART, which initially supports downloading multiple dex files from the application’s APK files.

Now, it would seem that with multiposition and trying to support both “normal DEXING” (before 5.0 / API21) and “oats ART files” (new DEX files after 5.0 / API21) in one application, you may encounter some problems similar to mine (it was not possible to find some methods before API21, but the application works fine on API21 and higher).

My application fell within the 65k method limit and I had to support API17 +.

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

Associated code (in the 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' } } 

This is not a real solution, of course, since someone who needs to use the 65k methods efficiently will use multidex, but he did a great job and I can't spend more time on these problems.

Hope this helps someone.

0
source

All Articles