Android ProGuard +MultiDex causes ClassNotFoundException

二次信任 提交于 2019-12-04 21:10:10

问题


I have MultiDex enabled in my android project. It was working fine until I tried enabling proguard. I can successfully build the project but I get runtime exception on startup. It's unable to find the Application class and the MainActivity. I had the same problem before enabling MultiDex. Now I guess for some reason the MultiDex is not working properly with ProGuard. Here is what i get in the 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 

and after that the rest of the stack trace is about ClassNotFoundException for the MainActivity:

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

Edit- Here is my proguard rules file:

-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.**

回答1:


This page says:

The default proguard.cfg file tries to cover general cases, but you might encounter exceptions such as ClassNotFoundException, which happens when ProGuard strips away an entire class that your application calls.

You can fix errors when ProGuard strips away your code by adding a -keep line in the proguard.cfg file. For example:

-keep public class <MyClass>

There are many options and considerations when using the -keep option, so it is highly recommended that you read the ProGuard Manual for more information about customizing your configuration file. The Overview of Keep options and Examples sections are particularly helpful. The Troubleshooting section of the ProGuard Manual outlines other common problems you might encounter when your code gets stripped away.

Solution 1

You could try the following proguard.cfg I used to obfuscate the code while not optimising, and hence not remove classes/methods from your APK.

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-dontoptimize
-verbose

Solution 2

You have asked some classes to be kept but not for MainActivity. So you have to add this line:

-keep class com.mypackage.activities.MainActivity { *; }


来源:https://stackoverflow.com/questions/28577680/android-proguard-multidex-causes-classnotfoundexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!