Android Volley always fails with Proguard

天涯浪子 提交于 2020-02-08 03:11:28

问题


The goal is to deploy an application with obfuscation and minification applied. Usual builds without minification work fine. But when minifyEnabled is switched to true, everything compiles too, but all Volley requests fail with error callback (onErrorResponse) regardless on successful result.

Minification config in build.gradle:

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

proguard-rules.pro:

##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }

# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

##---------------End: proguard configuration for Gson  ----------



##---------------Begin: proguard configuration for Spongy Castle  ----------

-keep class org.spongycastle.crypto.* {*;}
-keep class org.spongycastle.crypto.digests.* {*;}
-keep class org.spongycastle.crypto.encodings.* {*;}
-keep class org.spongycastle.crypto.engines.* {*;}
-keep class org.spongycastle.crypto.macs.* {*;}
-keep class org.spongycastle.crypto.modes.* {*;}
-keep class org.spongycastle.crypto.paddings.* {*;}
-keep class org.spongycastle.crypto.params.* {*;}
-keep class org.spongycastle.crypto.prng.* {*;}
-keep class org.spongycastle.crypto.signers.* {*;}

-keep class org.spongycastle.jcajce.provider.digest.** {*;}
-keep class org.spongycastle.jcajce.provider.keystore.** {*;}
-keep class org.spongycastle.jcajce.provider.symmetric.** {*;}
-keep class org.spongycastle.jcajce.spec.* {*;}
-keep class org.spongycastle.jce.** {*;}

-dontwarn javax.naming.**

##---------------End: proguard configuration for Spongy Castle  ----------



# Configuration for Guava 18.0
#
# disagrees with instructions provided by Guava project: https://code.google.com/p/guava-libraries/wiki/UsingProGuardWithGuava

-keep class com.google.common.io.Resources {
    public static <methods>;
}
-keep class com.google.common.collect.Lists {
    public static ** reverse(**);
}
-keep class com.google.common.base.Charsets {
    public static <fields>;
}

-keep class com.google.common.base.Joiner {
    public static com.google.common.base.Joiner on(java.lang.String);
    public ** join(...);
}

-keep class com.google.common.collect.MapMakerInternalMap$ReferenceEntry
-keep class com.google.common.cache.LocalCache$ReferenceEntry

# http://stackoverflow.com/questions/9120338/proguard-configuration-for-guava-with-obfuscation-and-optimization
-dontwarn javax.annotation.**
-dontwarn javax.inject.**
-dontwarn sun.misc.Unsafe

# Guava 19.0
-dontwarn java.lang.ClassValue
-dontwarn com.google.j2objc.annotations.Weak
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement



# Security classes for keystore support
-dontwarn java.awt.**, javax.security.**, java.beans.**



# Volley
-dontwarn com.android.volley.**
-dontwarn com.android.volley.error.**
-keep class com.android.volley.** { *; }
-keep class com.android.volley.toolbox.** { *; }
-keep class com.android.volley.Response$* { *; }
-keep class com.android.volley.Request$* { *; }
-keep class com.android.volley.RequestQueue$* { *; }
-keep class com.android.volley.toolbox.HurlStack$* { *; }
-keep class com.android.volley.toolbox.ImageLoader$* { *; }
-keep interface com.android.volley.** { *; }
-keep class org.apache.commons.logging.*

All used dependencies:

compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0' 

compile 'com.google.code.gson:gson:2.7'
compile 'com.android.volley:volley:1.0.0' 
compile 'com.google.guava:guava:19.0'
compile 'org.apache.directory.studio:org.apache.commons.io:2.4'

compile 'com.madgag.spongycastle:core:1.54.0.0'
compile 'com.madgag.spongycastle:prov:1.54.0.0'
compile 'com.madgag.spongycastle:pkix:1.54.0.0'
compile 'com.madgag.spongycastle:pg:1.54.0.0'

And in addition to Volley failures, EventBus from Guava doesn't work correctly too (subscribe events are not fetching). Do we have any solutions for these troubles? Should I add any additional information here?


回答1:


Should admit, that even with all information provided, my question was very difficult to analyze, because of many possible sources of described errors.

I'll begin from the end of my question. Guava didn't work correctly, because ProGuard just excluded Guava's Subscribe-methods from my code to be packed. ProGuard removes unused code, and as far as Subscribe-methods are analyzed as unused (even IDE don't highlight them as used ones) ProGuard has decided to remove these methods. To solve this issue, we should keep Subscribe-methods from ProGuard's processing:

# Keep subscribe-methods from deletion
-keepclassmembers class ** {
  @com.google.common.eventbus.Subscribe <methods>;
}

And my first problem - when Volley always calls onErrorResponse callbacks in all requests being fired. I used a custom deserializer for Json-repsonses which also checks, if server has provided some required fields (marked with a corresponding annotation). And, of course, ProGuard by default could not work correctly with these annotations and deserializer - that's why I had to keep these entities too:

# To make right deserialization
-keepclassmembers class ** {
  @com.some.package.server.JsonDeserializerWithOptions$FieldRequired public *;
}
-keep @interface com.some.package.server.JsonDeserializerWithOptions$FieldRequired
-keep class com.some.package.server.JsonDeserializerWithOptions



回答2:


Its difficult the pinpoint any error with the logs, however you should try it without using proguard. skip the proguard file syntax and see if it works fine. Make sure you have multidex enabled, else your project will fail to execute.

android {

compileSdkVersion 21
buildToolsVersion "21.1.0"

defaultConfig {
    ...
    minSdkVersion 14
    targetSdkVersion 21
    ...

    // Enabling multidex support.
    multiDexEnabled true
}
...
}

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

More details : https://developer.android.com/studio/build/multidex.html



来源:https://stackoverflow.com/questions/39868072/android-volley-always-fails-with-proguard

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