Error MultiDex NoClassDefFound

He convertido mi aplicación en MultiDex para soportar un límite de 64k dex. Ahora se ve así:

public class App extends MultiDexApplication { private AppWrapper instance; @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(base); } @Override public void onCreate() { super.onCreate(); if (instance == null) { instance = new AppWrapper(this); } } } 

Extraje toda la lógica habitual de la aplicación a AppWidget para que funcione MultiDex . Y funciona bien en las computadoras de otros compañeros. Pero no conmigo. Sigue lanzando java.lang.NoClassDefFoundError en la aplicación create:

 I/dalvikvm﹕ Failed resolving Lcom/playday/app/core/AppWrapper; interface 8940 'Lretrofit/ErrorHandler;' W/dalvikvm﹕ Link of class 'Lcom/playday/app/core/AppWrapper;' failed I/dalvikvm﹕ Failed resolving Lcom/playday/app/core/AppWrapper; interface 8940 'Lretrofit/ErrorHandler;' W/dalvikvm﹕ Link of class 'Lcom/playday/app/core/AppWrapper;' failed E/dalvikvm﹕ Could not find class 'com.playday.app.core.AppWrapper', referenced from method com.playday.app.core.App.onCreate W/dalvikvm﹕ VFY: unable to resolve new-instance 7076 (Lcom/playday/app/core/AppWrapper;) in Lcom/playday/app/core/App; D/dalvikvm﹕ VFY: replacing opcode 0x22 at 0x0007 I/dalvikvm﹕ Failed resolving Lcom/playday/app/core/AppWrapper; interface 8940 'Lretrofit/ErrorHandler;' W/dalvikvm﹕ Link of class 'Lcom/playday/app/core/AppWrapper;' failed D/dalvikvm﹕ DexOpt: unable to opt direct call 0xc21b at 0x09 in Lcom/playday/app/core/App;.onCreate I/MultiDex﹕ VM with version 1.6.0 does not have multidex support I/MultiDex﹕ install I/MultiDex﹕ MultiDexExtractor.load( /data/app/com.playdayteam.playday.debug-1.apk, false) I/MultiDex﹕ Detected that extraction must be performed. I/MultiDex﹕ Trying to delete old file /data/data/com.playdayteam.playday.debug/code_cache/secondary-dexes/com.playdayteam.playday. debug-2.apk.classes2.dex of size 1484912 I/MultiDex﹕ Deleted old file /data/data/com.playdayteam.playday.debug/code_cache/secondary-dexes/com.playdayteam.playday.debug-2 .apk.classes2.dex I/MultiDex﹕ Trying to delete old file /data/data/com.playdayteam.playday.debug/code_cache/secondary-dexes/com.playdayteam.playday. debug-2.apk.classes2.zip of size 540964 I/MultiDex﹕ Deleted old file /data/data/com.playdayteam.playday.debug/code_cache/secondary-dexes/com.playdayteam.playday.debug-2 .apk.classes2.zip D/dalvikvm﹕ GC_CONCURRENT freed 186K, 11% free 3245K/3640K, paused 2ms+4ms, total 28ms D/dalvikvm﹕ WAIT_FOR_CONCURRENT_GC blocked 5ms D/dalvikvm﹕ GC_CONCURRENT freed 156K, 8% free 3593K/3904K, paused 3ms+2ms, total 22ms I/MultiDex﹕ Extraction is needed for file /data/data/com.playdayteam.playday.debug/code_cache/secondary-dexes/com.playdayteam. playday.debug-1.apk.classes2.zip I/MultiDex﹕ Extracting /data/data/com.playdayteam.playday.debug/code_cache/secondary-dexes/com.playdayteam.playday.debug-1 .apk.classes576886388.zip I/MultiDex﹕ Renaming to /data/data/com.playdayteam.playday.debug/code_cache/secondary-dexes/com.playdayteam.playday.debug-1 .apk.classes2.zip I/MultiDex﹕ Extraction success - length /data/data/com.playdayteam.playday.debug/code_cache/secondary-dexes/com.playdayteam.playday. debug-1.apk.classes2.zip: 540964 I/MultiDex﹕ load found 1 secondary dex files D/dalvikvm﹕ DexOpt: --- BEGIN 'com. playdayteam.playday.debug-1.apk.classes2.zip' (bootstrap=0) --- D/dalvikvm﹕ DexOpt: --- END 'com. playdayteam.playday.debug-1.apk.classes2.zip' (success) --- D/dalvikvm﹕ DEX prep '/data/data/com .playdayteam.playday.debug/code_cache/secondary-dexes/com.playdayteam.playday.debug-1.apk.classes2. zip': unzip in 28ms, rewrite 387ms I/MultiDex﹕ install done I/MultiDex﹕ install D/AndroidRuntime﹕ Shutting down VM W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41c1d930) E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.NoClassDefFoundError: com.playday.app.core.AppWrapper at com.playday.app.core.App.onCreate(App.java:22) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1006) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4457) at android.app.ActivityThread.access$1300(ActivityThread.java:142) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1332) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5105) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method) 

Tengo las mismas versiones de Android Studio, gradle, sdk, jdk, mismo código. Incluso he tratado de formatear el disco duro y reinstalar el sistema operativo para asegurarme de que el entorno sea el mismo. ¿Cuál puede ser la causa de este extraño problema?

Este es mi build.gradle :

 apply plugin: 'com.android.application' repositories { maven { url 'http://dl.bintray.com/populov/maven' } mavenCentral() maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } android { compileSdkVersion project.api_level buildToolsVersion project.build_tools_version defaultConfig { minSdkVersion 14 targetSdkVersion project.api_level } sourceSets { instrumentTest.setRoot('src/test') } packagingOptions { exclude 'META-INF/LICENSE.txt' exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/ASL2.0' exclude 'AndroidManifest.xml' } defaultConfig { versionName "0.3.2" versionCode 23 } buildTypes { debug { debuggable true applicationIdSuffix ".debug" } beta { debuggable true signingConfig signingConfigs.release applicationIdSuffix ".beta" } release { signingConfig signingConfigs.release runProguard false proguardFile file('proguard-rules.txt') proguardFile getDefaultProguardFile('proguard-android-optimize.txt') } } dexOptions { incremental false preDexLibraries false } } dependencies { compile "com.android.support:support-v13:$project.support_lib_version" compile "com.android.support:support-v4:$project.support_lib_version" compile "com.android.support:appcompat-v7:$project.support_lib_version" compile 'com.google.android.gms:play-services:6.1.11' compile('de.keyboardsurfer.android.widget:crouton:1.8.5@aar') { exclude group: 'com.google.android', module: 'support-v4' } compile('com.octo.android.robospice:robospice:1.4.14'){ exclude group: 'commons-io', module: 'commons-io' } compile('com.octo.android.robospice:robospice-retrofit:1.4.14'){ exclude group: 'commons-io', module: 'commons-io' } compile 'com.squareup.retrofit:retrofit:1.6.1' compile 'com.google.code.gson:gson:2.3' compile 'com.viewpagerindicator:library:2.4.1@aar' compile 'com.squareup.picasso:picasso:2.3.3' compile 'com.squareup.okhttp:okhttp:2.0.0' compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0' compile 'com.etsy.android.grid:library:1.0.5' compile 'com.squareup:otto:1.3.4' compile 'com.darwinsys:hirondelle-date4j:1.5.1' compile 'com.github.chrisbanes.photoview:library:1.2.3' compile 'me.grantland:autofittextview:0.2.0' compile 'it.sephiroth.android.library.horizontallistview:library:1.2.1' compile 'org.ocpsoft.prettytime:prettytime:3.2.4.Final' compile 'com.google.guava:guava:18.0' compile 'com.github.castorflex.smoothprogressbar:library:0.5.2' compile 'com.makeramen:roundedimageview:1.3.0' compile 'org.lucasr.twowayview:twowayview:0.1.1' compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT' compile project(':libs:LoopingViewPager') compile project(':libs:PhotoView-2.2.1') compile files('libs/localytics.jar') compile files('libs/android-support-multidex.jar') compile 'net.hockeyapp.android:HockeySDK:3.0.2' } afterEvaluate { tasks.matching { it.name.startsWith('dex') }.each { dx -> if (dx.additionalParameters == null) { dx.additionalParameters = [] } dx.additionalParameters += '--multi-dex' // enable multidex dx.additionalParameters += "--main-dex-list=$projectDir/multidex.keep".toString() } } 

Actualizar. Mi archivo multidex.keep :

 android/support/multidex/BuildConfig.class android/support/multidex/MultiDex$V14.class android/support/multidex/MultiDex$V19.class android/support/multidex/MultiDex$V4.class android/support/multidex/MultiDex.class android/support/multidex/MultiDexApplication.class android/support/multidex/MultiDexExtractor$1.class android/support/multidex/MultiDexExtractor.class android/support/multidex/ZipUtil$CentralDirectory.class android/support/multidex/ZipUtil.class com/playday/app/models/notification/Badge.class com/playday/app/models/User.class com/playday/app/core/AppWrapper.class com/playday/app/core/App.class 

Su clase AppWrapper no se carga porque la interfaz retrofit.ErrorHandler no está incluida en el archivo principal dex.

¿Cómo se calcula qué clases poner en su archivo main-dex-list?
Hay un script que puede generarlo para usted. Escribí un blog que muestra cómo usarlo.

Actualización (31/10/2014) :
El complemento Gradle v0.14.0 ahora lo hace automáticamente. Vea mi respuesta aquí .

Actualización (24/04/2017) :
La guía para desarrolladores explica cómo seleccionar clases específicas con una opción de gradle si no selecciona todas las correctas automáticamente.

Si está ampliando la aplicación MultiDex, no necesita realizar la llamada MultiDex.install (contexto) ya que está sucediendo (consulte el enlace de origen). Si necesita usar attachBaseContext, simplemente asegúrese de llamar a super.attachBaseContext (context).

https://android.googlesource.com/platform/frameworks/multidex/+/1bb1ab007f6b9405227ea4ce07d2061e4dbb6fe0/library/src/android/support/multidex/MultiDexApplication.java

Acabamos de actualizar developers.android.com con instrucciones sobre cómo usar la biblioteca de soporte con el complemento gradle de Android, que incluye una optimización de desarrollo para tiempos de ciclo de comstackción de desarrollo rápido.

https://developer.android.com/tools/building/multidex.html

Si alguien llega aquí porque su clase de aplicación no se encuentra en dispositivos anteriores a Lollipop, pero la aplicación funciona bien en Lollipop y superior, parece ser un problema conocido con Jack y Multidex.

Ref: Jack Issue 213484

Ref .: Jack Issue 224026

si todo parece estar bien, pero aparece este error,

intente deshabilitar la ejecución instantánea !!!

cuando lo desactivé, todas las clases se cargaron correctamente.

El NoClassDefFound puede ocurrir con cualquier clase arbitraria que no se haya cargado en un dispositivo con API anterior a Lollipop y con multidex habilitado. Si configura ProGuard de manera adecuada, puede pasar fácilmente sin tener que hacer que la aplicación de MultiDex haga que su aplicación sea más lenta para iniciarse en las comstackciones de lanzamiento , especialmente en dispositivos antiguos. Sin embargo, no desea que ProGuard le ralentice mientras desarrolla su aplicación en modo de depuración. Si intenta iniciar su comstackción de depuración con ProGuard deshabilitado, comenzará a tener errores de comstackción como com.android.dex.DexIndexOverflowException: Cannot merge new index 72118 into a non-jumbo instruction!

Entonces, lo que realmente quiere es ProGuard habilitado y multidex inhabilitado solo en comstackciones de versiones, mientras que las comstackciones de depuración deberían ser lo opuesto con Proguard deshabilitado y multidex habilitado. También debe ser exigente y usar menos dependencias, por supuesto, porque su versión de lanzamiento estará sujeta al límite de 64 KB.

Esto requiere configurar build.gradle para tener buildTypes configuraciones de buildTypes , y comstackr la dependencia de la biblioteca de soporte multidex solo para la depuración.

La subclase Application también se debe configurar para derivar de una subclase diferente dependiendo de si está en modo multidex o no. Esto se puede lograr utilizando el principio de fusión de manifiesto de Gradle, definiendo un manifiesto de sustitución para su comstackción de depuración y luego especificando su clase de Aplicación de forma diferente.

Aquí está el módulo de aplicación relevante build.gradle:

 android { ... buildTypes { debug { minifyEnabled false //Disabled Proguard multiDexEnabled true // Enabling multi-dex support. } release { minifyEnabled true //Enabled Proguard proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' multiDexEnabled false // Disable multi-dex support. } } dependencies { debugCompile 'com.android.support:multidex:1.0.1' //debugCompile makes it included only for debug builds ... } } 

Si no usa una subclase de Aplicación, entonces todo lo que necesita hacer es especificar el nombre de la subclase de Aplicación android.support.multidex.MultiDexApplication como se indica en https://developer.android.com/studio/build/multidex. html pero desea hacer esto solo para su comstackción de depuración.

Para esto, debe especificar la sobreescritura de archivos en la jerarquía de carpetas de variantes de depuración y liberación, así:

 src - main - AndroidManifest.xml - java/com/yourcompany/MyApplication.java (extends from BaseApplication) - release - java/com/yourcompany/BaseApplication.java (extends from Application) - debug - AndroidManifest.xml - java/com/yourcompany/BaseApplication.java (extends from MultiDexApplication) 

Sí, crea carpetas de debug y release junto a la carpeta de su módulo principal. Agregue los siguientes archivos dentro de:

debug / AndroidManifest.xml

 < ?xml version="1.0" encoding="utf-8"?>    

Este manifiesto solo se incluirá en comstackciones de depuración y se ignorará para su versión uno.

release / java / com / yourcompany / BaseApplication.java

 public class BaseApplication extends Application { } 

debug / java / com / yourcompany / BaseApplication.java

 public class BaseApplication extends MultiDexApplication { } 

main / java / com / yourcompany / MyApplication.java

 public class MyApplication extends BaseApplication { @Override public void onCreate() { super.onCreate(); //Init database, etc. etc.; } } 

De esta forma, puede agregar la funcionalidad de su Aplicación en MyApplication.java mientras tiene diferentes clases base.

También tengo este tipo de problema. La solución en mi caso era: en mi archivo build.gradle, había varias entradas de compile 'com.android.support:multidex:1.0.0' en dependencias. me gusta:

 dependencies { compile 'com.android.support:multidex:1.0.0' compile 'com.android.support:multidex:1.0.0' // other dependencies ........ } 

simplemente ponga solo una comstackción ‘com.android.support:multidex:1.0.0’ como:

 dependencies { compile 'com.android.support:multidex:1.0.0' // other dependencies ........ } 

¡Finalmente lo resolví! Causa no estaba en el método onCreate() Hubo esta línea de Logcat que me llamó la atención:

 I/dalvikvm﹕ Failed resolving Lcom/playday/app/core/AppWrapper; interface 8940 'Lretrofit/ErrorHandler;' W/dalvikvm﹕ Link of class 'Lcom/playday/app/core/AppWrapper;' failed 

Esta línea se disparó antes de todo el registro de MultiDex. El origen del problema fue la interfaz Retrofit ErrorHandler , que AppWrapper implementa.

Como @AlexLipov dijo en su respuesta, Dalvik simplemente no pudo encontrar la clase ErrorHandler y no pudo cargar el AppWrapper .

De todos modos, la solución no es implementar ErrorHandler directamente por AppWrapper y, en su lugar, colocarlo en una variable privada.