Android Volley总是在Proguard失败

时间:2016-10-05 07:39:48

标签: android android-gradle android-volley proguard android-proguard

目标是部署应用了obfuscationminification的应用。没有minification的常用版本可以正常工作。但是当minifyEnabled切换为true时,所有内容都会编译,但无论成功结果如何,所有Volley个请求都会失败并返回错误(onErrorResponse)。

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

所有使用的依赖项:

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'

除了Volley失败之外,来自EventBus的{​​{1}}也无法正常工作(订阅事件无法获取)。我们有解决这些问题的方法吗?我应该在这里添加任何其他信息吗?

2 个答案:

答案 0 :(得分:0)

很难确定日志中的任何错误,但是你应该在不使用proguard的情况下尝试它。跳过proguard文件语法,看看它是否正常工作。 确保启用了multidex,否则您的项目将无法执行。

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'
}

更多详情:https://developer.android.com/studio/build/multidex.html

答案 1 :(得分:0)

应该承认,即使提供了所有信息,我的问题也很难分析,因为所描述错误的许多可能来源。

我将从问题的结尾开始。 Guava无法正常工作,因为ProGuard只是将我的代码中的Guava的Subscribe-methods排除在外。 ProGuard删除了未使用的代码,并且只要将Subscribe-methods分析为未使用(即使IDE不将它们突出显示为已使用的代码),ProGuard也决定删除这些方法。要解决这个问题,我们应该保留来自ProGuard处理的订阅方法:

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

我的第一个问题 - 当Volley总是在所有被触发的请求中调用onErrorResponse回调。我为Json-repsonses使用了一个自定义反序列化程序,如果服务器提供了一些必需的字段(用相应的注释标记),它也会检查。当然,默认情况下,ProGuard无法正确使用这些注释和反序列化器 - 这也是我必须保留这些实体的原因:

# 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