Android ProGuard + MultiDex causa ClassNotFoundException
Tengo MultiDex
habilitado en mi proyecto androide. Estaba funcionando bien hasta que intenté habilitar proguard. Puedo construir con éxito el proyecto pero consigo la excepción del tiempo de ejecución en el arranque. No puede encontrar la clase Application y MainActivity
. Tuve el mismo problema antes de habilitar MultiDex
. Ahora supongo que por alguna razón MultiDex
no está funcionando correctamente con ProGuard
. Esto es lo que obtengo en el logcat –
02-17 19:01:09.749: I/MultiDex(2079): VM with version 2.1.0 has multidex support 02-17 19:01:09.749: I/MultiDex(2079): install 02-17 19:01:09.749: I/MultiDex(2079): VM has multidex support, MultiDex support library is disabled. 02-17 19:01:09.750: I/art(2079): Rejecting re-init on previously-failed class java.lang.Class<android.support.v4.app.FragmentActivity> 02-17 19:01:09.750: I/art(2079): Rejecting re-init on previously-failed class java.lang.Class<android.support.v4.app.FragmentActivity> 02-17 19:01:09.751: I/art(2079): Rejecting re-init on previously-failed class java.lang.Class<mypackage.activities.MainActivity> 02-17 19:01:09.751: I/art(2079): Rejecting re-init on previously-failed class java.lang.Class<mypackage.activities.MainActivity> 02-17 19:01:09.751: D/AndroidRuntime(2079): Shutting down VM 02-17 19:01:09.751: D/AndroidRuntime(2079): --------- beginning of crash
Y después de que el resto de la traza de pila es sobre ClassNotFoundException para MainActivity:
- ¿Cómo Proguard dos proyecto androide?
- Android Proguard - IllegalArgumentException en la clase TypeReference de Jackson
- Crashlytics ProGuard duplicate zip entry
- Pruebas de unidad de Android con proguard activado
- Pase 1.1.3 - Proguard
02-17 19:01:09.752: E/AndroidRuntime(2079): FATAL EXCEPTION: main 02-17 19:01:09.752: E/AndroidRuntime(2079): Process: com.mypackage, PID: 2079 02-17 19:01:09.752: E/AndroidRuntime(2079): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/mypackage/activities/MainActivity; 02-17 19:01:09.752: E/AndroidRuntime(2079): at cmypackage.application.ApplicationContextProvider.onCreate(Unknown Source) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4518) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.ActivityThread.access$1500(ActivityThread.java:144) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.os.Handler.dispatchMessage(Handler.java:102) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.os.Looper.loop(Looper.java:135) 02-17 19:01:09.752: E/AndroidRuntime(2079): at android.app.ActivityThread.main(ActivityThread.java:5221) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.reflect.Method.invoke(Native Method) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.reflect.Method.invoke(Method.java:372) 02-17 19:01:09.752: E/AndroidRuntime(2079): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 02-17 19:01:09.752: E/AndroidRuntime(2079): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 02-17 19:01:09.752: E/AndroidRuntime(2079): Caused by: java.lang.ClassNotFoundException: Didn't find class "mypackage.activities.MainActivity" on path: DexPathList[[zip file "/data/app/mypackage-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]] 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.ClassLoader.loadClass(ClassLoader.java:511) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.ClassLoader.loadClass(ClassLoader.java:469) 02-17 19:01:09.752: E/AndroidRuntime(2079): ... 12 more 02-17 19:01:09.752: E/AndroidRuntime(2079): Suppressed: java.lang.NoClassDefFoundError: mypackage.activities.MainActivity 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.DexFile.defineClassNative(Native Method) 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.DexFile.defineClass(DexFile.java:226) 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:219) 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.DexPathList.findClass(DexPathList.java:321) 02-17 19:01:09.752: E/AndroidRuntime(2079): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54) 02-17 19:01:09.752: E/AndroidRuntime(2079): ... 14 more 02-17 19:01:09.752: E/AndroidRuntime(2079): Suppressed: java.lang.ClassNotFoundException: mypackage.MainActivity 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.Class.classForName(Native Method) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.BootClassLoader.findClass(ClassLoader.java:781) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841) 02-17 19:01:09.752: E/AndroidRuntime(2079): at java.lang.ClassLoader.loadClass(ClassLoader.java:504) 02-17 19:01:09.752: E/AndroidRuntime(2079): ... 13 more 02-17 19:01:09.752: E/AndroidRuntime(2079): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
Editar- Aquí está mi archivo de reglas proguard:
-libraryjars libs # We only want obfuscation -keepattributes InnerClasses,Signature -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -dontoptimize -verbose # Sdk -keep public interface com.zendesk.sdk.** { *; } -keep public class com.zendesk.sdk.** { *; } # Appcompat and support #-keep interface android.support.v7.** { *; } #-keep class android.support.v7.** { *; } #-keep interface android.support.v4.** { *; } #-keep class android.support.v4.** { *; } # Gson -keep interface com.google.gson.** { *; } -keep class com.google.gson.** { *; } # Retrofit #-keep class com.google.inject.** { *; } #-keep class org.apache.http.** { *; } #-keep class org.apache.james.mime4j.** { *; } #-keep class javax.inject.** { *; } #-keep class retrofit.** { *; } #-keep interface retrofit.** { *; } # Retrofit -keep class com.squareup.okhttp.** { *; } -keep interface com.squareup.okhttp.** { *; } -dontwarn com.squareup.okhttp.** -dontwarn rx.** -dontwarn retrofit.** -dontwarn okio.** -keep class retrofit.** { *; } -keepclasseswithmembers class * { @retrofit.http.* <methods>; } # Jackson -keepattributes *Annotation*,EnclosingMethod,Signature -keepnames class com.fasterxml.jackson.** { *; } -dontwarn com.fasterxml.jackson.databind.** -keep class org.codehaus.** { *; } -keepclassmembers public final enum org.codehaus.jackson.annotate.JsonAutoDetect$Visibility { public static final org.codehaus.jackson.annotate.JsonAutoDetect$Visibility *; } -keep public class mypackage.parsers.JacksonParser.** { public void set*(***); public *** get*(); } #Picasso -dontwarn com.squareup.okhttp.** #-dontwarn javax.management.** #-dontwarn java.lang.management.** #-dontwarn org.apache.log4j.** #-dontwarn org.apache.commons.logging.** #-dontwarn org.json.* #-dontwarn org.apache.commons.codec.binary.Base64 #-keep class javax.** {* ; } #-keep class org.** { *; } -dontwarn org.mortbay.** -dontwarn org.slf4j.** -dontwarn org.apache.log4j.** -dontwarn org.apache.commons.logging.** -dontwarn org.apache.commons.codec.binary.**
- Proguard: no se puede encontrar la clase referenciada
- Android Proguard - ¿es la mejor práctica mantener todas las librerías de terceros?
- Problema con proguardFile, null devuelto: 1
- Usando jsoup con fuerza de cierre proguard cerrar
- ¿Cómo decirle a ProGuard que guarde todo en un paquete en particular?
- ProGuard para Android y GSON
- Proguard error: opción desconocida '-optimizationpasses'
- Proguard elimina clase Anonymous en clase Anonymous en Java
Esta página dice:
El archivo
proguard.cfg
predeterminado intenta cubrir casos generales, pero es posible que encuentre excepciones comoClassNotFoundException
, lo que sucede cuando ProGuard elimina una clase completa que su aplicación llama.Puede corregir errores cuando ProGuard quita el código añadiendo una línea de
-keep
en el archivoproguard.cfg
. Por ejemplo:-keep public class <MyClass>
Hay muchas opciones y consideraciones al usar la opción -keep, por lo que es muy recomendable que lea el Manual de ProGuard para obtener más información acerca de cómo personalizar su archivo de configuración. Las secciones Resumen de opciones de mantenimiento y Ejemplos son particularmente útiles. La sección Solución de problemas del Manual de ProGuard esboza otros problemas comunes que puede encontrar cuando el código se quita.
Solución 1
Usted podría intentar el proguard.cfg
siguiente que utilizó para ofuscar el código mientras que no optimiza, y por lo tanto no quita clases / métodos de su APK.
-dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -dontoptimize -verbose
Solución 2
Ha solicitado que se mantengan algunas clases, pero no para MainActivity
. Así que tienes que añadir esta línea:
-keep class com.mypackage.activities.MainActivity { *; }
- Asegúrese de que mi código es seguro para hilos
- Cualquier manera de forzar la aplicación de memoria en el emulador de Android?