Android 带有proguard的渐变发布版本:java.lang.CompatibileClassChangeError和java.lang.NoSuchMethodError

Android 带有proguard的渐变发布版本:java.lang.CompatibileClassChangeError和java.lang.NoSuchMethodError,android,proguard,dropbox-api,box-api,android-gradle-plugin,Android,Proguard,Dropbox Api,Box Api,Android Gradle Plugin,我最近将一个项目从Eclipse/Ant迁移到Android Studio/Gradle。我能够在启用proguard的情况下成功构建项目的签名发布版本。然而,在测试发布版本时,我发现某些库项目和JAR(在构建调试版本时工作正常)会导致崩溃 例如,当尝试将文件上载到Dropbox(jar依赖项)时,我遇到以下错误: java.lang.IncompatibleClassChangeError: interface not implemented at com.dropbox.client2

我最近将一个项目从Eclipse/Ant迁移到Android Studio/Gradle。我能够在启用proguard的情况下成功构建项目的签名发布版本。然而,在测试发布版本时,我发现某些库项目和JAR(在构建调试版本时工作正常)会导致崩溃

例如,当尝试将文件上载到Dropbox(jar依赖项)时,我遇到以下错误:

java.lang.IncompatibleClassChangeError: interface not implemented
   at com.dropbox.client2.session.AbstractSession.sign(SourceFile:238)
   at com.dropbox.client2.DropboxAPI.putFileRequest(SourceFile:2199)
   at com.dropbox.client2.DropboxAPI.putFileOverwriteRequest(SourceFile:1571)
   at com.dropbox.client2.DropboxAPI.putFileOverwrite(SourceFile:1537)
java.lang.NoSuchMethodError: org.apache.http.conn.params.ConnManagerParams.setMaxTotalConnections
   at com.box.restclientv2.BoxBasicRestClient.()
   at com.box.boxjavalibv2.BoxRESTClient.()
   at com.box.boxjavalibv2.BoxClient.createRestClient()
   at com.box.boxjavalibv2.BoxClient.()
   at com.box.boxandroidlibv2.BoxAndroidClient.(SourceFile:49)
   at com.box.boxandroidlibv2.activities.OAuthActivity.startOAuth(SourceFile:71)
   at com.box.boxandroidlibv2.activities.OAuthActivity.onCreate(SourceFile:52)
此外,当尝试登录到Box(库项目依赖项)时,我会出现以下错误:

java.lang.IncompatibleClassChangeError: interface not implemented
   at com.dropbox.client2.session.AbstractSession.sign(SourceFile:238)
   at com.dropbox.client2.DropboxAPI.putFileRequest(SourceFile:2199)
   at com.dropbox.client2.DropboxAPI.putFileOverwriteRequest(SourceFile:1571)
   at com.dropbox.client2.DropboxAPI.putFileOverwrite(SourceFile:1537)
java.lang.NoSuchMethodError: org.apache.http.conn.params.ConnManagerParams.setMaxTotalConnections
   at com.box.restclientv2.BoxBasicRestClient.()
   at com.box.boxjavalibv2.BoxRESTClient.()
   at com.box.boxjavalibv2.BoxClient.createRestClient()
   at com.box.boxjavalibv2.BoxClient.()
   at com.box.boxandroidlibv2.BoxAndroidClient.(SourceFile:49)
   at com.box.boxandroidlibv2.activities.OAuthActivity.startOAuth(SourceFile:71)
   at com.box.boxandroidlibv2.activities.OAuthActivity.onCreate(SourceFile:52)
我有其他的JAR和库项目,工作得很好

同样,在构建gradle调试构建(无proguard)时,这两个方面都没有问题。我还能够使用ant创建一个启用proguard的发布版本,没有任何问题(能够登录Dropbox和Box)


有什么想法吗?

您需要
-防止
Proguard删除或重命名它无法确定的所有类和方法名称,这些名称是从它不处理的代码中引用的,这些名称是通过反射引用的(例如,XML引用),等等

保留所有apache类可能会保留更多(这是可以的),但这可能不足以修复所有Proguard问题


问一下为什么在没有这个
-keep
的情况下,它可以从ant构建中运行是很好的。可能ant构建实际上没有调用Proguard(ant很棘手),可能它使用了不同的Proguard数据文件,或者可能相关的库在此期间发生了变化。您可以通过列出假设并对其进行测试来调试。例如,如果在Proguard数据文件中放入格式错误的命令,然后运行ant构建,则可以判断它是否实际运行Proguard。

您似乎包含了org.apache.http库的一个版本。原则上,这个库已经是Android运行时Android.jar的一部分,所以您不应该将它添加到您的项目中。ProGuard可能正在打印关于这些重复类的警告

实际上,它可能是库的较新版本,并且您的一些代码可能正在使用此版本中的其他类。然后,您可能应该保持类、字段和方法的名称不变,以避免引入(其他)冲突:

-keep class org.apache.http.** { *; }

一个构建过程可能会过滤掉这些类,或者它可能会添加上面这一行,但我认为默认的Android构建目前也不会这样做。

添加proguard规则
-keep class org.apache.http.*{*;}
似乎“修复”了这两个崩溃。我仍然对此感到有点不舒服,因为当我使用Ant构建项目时,并不需要这个proguard规则。这条规则确实解释了为什么它修复了Box崩溃的
NoSuchMethodError
,但没有修复Dropbox崩溃。有人能提供解释吗?比较构建是个好主意。您可以让ProGuard写出它与
-printconfiguration conf.txt
一起使用的配置。这将包括输入jar和库jar.Jerry101,我了解proguard是如何工作的,并且我确信proguard在我的ant构建中运行(我有很多缺少的proguard规则,我在过去不得不寻找)@艾丽卡:谢谢。我看看能不能比较一下配置。我仍然认为新的Android gradle构建系统存在一些可疑之处。似乎它并没有“保护”Android SDK的某些部分免受proguard的攻击(例如org.apache.http包)。我在这里提交了一个bug报告:很高兴您正在调试这个并提交了一个bug。更多调试想法:创建一个调用apache.http来重现问题的最小测试项目。使用Proguard设置printconfiguration、dump和verbose查看它在做什么,以及它使用什么配置。将实际配置与ant构建进行比较。由于典型的gradle构建使用标准的proguard配置文件+特定于项目的配置文件,因此问题可能出在前者,尽管如果该库位于操作系统中而不是APK中,这仍然是可疑的。