使用proguard构建Gradle:java.lang.IncompatibleClassChangeError和java.lang.NoSuchMethodError

时间:2014-03-13 23:47:31

标签: android proguard dropbox-api box-api android-gradle

我最近将项目从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)

此外,当尝试登录Box(库项目依赖项)时,我收到以下错误:

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)

我有其他罐子和图书馆项目可以正常工作......

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

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

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

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

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

构建过程可能会过滤掉类,或者可能会添加上述行,但我不认为默认的Android版本当前也会这样做。

答案 1 :(得分:0)

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

保持所有apache类可能保持不必要(这没关系)但是它可能不足以解决所有Proguard问题。

如果没有这个-keep,可以从你的ant构建中找到它的工作原理。也许ant build实际上没有调用Proguard(ant很棘手),也许它使用了不同的Proguard数据文件,或者同时更改了相关的库。您可以通过列出假设并测试它们来调试它。例如。如果你在Proguard数据文件中输入格式错误的命令然后运行ant build,你可以判断它是否实际运行了Proguard。