Proguard for Wire + Retrofit NoSuchMethodException

Posted

技术标签:

【中文标题】Proguard for Wire + Retrofit NoSuchMethodException【英文标题】: 【发布时间】:2016-11-19 07:54:26 【问题描述】:

我的大脑被炸了。我搜索了 S.O.寻求帮助,但似乎带有此异常的 Proguard 问题特定于相关应用程序。我一直在尝试使用 Proguard 来混淆/缩小我的应用程序,当我在 Generated APK 表单中运行它时,我的应用程序要么崩溃,要么遇到以下问题:

com.company.project E/a: java.lang.NoSuchMethodException: fromValue [int]

堆栈跟踪:

java.lang.AssertionError: java.lang.NoSuchMethodException: fromValue [int]
     at com.squareup.wire.RuntimeEnumAdapter.decode(Unknown Source)
     at com.squareup.wire.RuntimeEnumAdapter.getFromValueMethod(Unknown Source)
     at com.squareup.wire.RuntimeEnumAdapter.decode(Unknown Source)
     at com.company.project.utils.wiremodels.d.a(Unknown Source)
     at com.company.project.utils.wiremodels.d.decode(Unknown Source)
     at com.company.project.utils.wiremodels.g.a(Unknown Source)
     at com.company.project.utils.wiremodels.g.decode(Unknown Source)
     at com.squareup.wire.ProtoAdapter.decode(Unknown Source)
     at retrofit2.converter.wire.WireResponseBodyConverter.convert(Unknown Source)
     at retrofit2.converter.wire.WireResponseBodyConverter.convert(Unknown Source)
     at retrofit2.ServiceMethod.toResponse(Unknown Source)
     at retrofit2.OkHttpCall.parseResponse(Unknown Source)
     at retrofit2.OkHttpCall$1.onResponse(Unknown Source)
     at a.az.b(Unknown Source)
     at a.a.l.run(Unknown Source)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
     at java.lang.Thread.run(Thread.java:818)
 Caused by: java.lang.NoSuchMethodException: fromValue [int]
     at java.lang.Class.getMethod(Class.java:624)
     at java.lang.Class.getMethod(Class.java:603)
    ... 18 more

我的应用使用了来自 Square 的 Retrofit (2.1.0) 和 Wire。然后,当我的应用程序崩溃时,我会检查 mapping.txt 文件以查看导致问题的类(我相信是 com.company.project.a,对吧?)

无论如何,这是我的 proguard 文件(带有晦涩的类名,仅供参考):

-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8
-dontwarn retrofit2.**
-keep class retrofit2.**  *; 
-keep class com.squareup.wire.**  *; 
-keep class com.company.project.utils.wiremodels.ProtoFile1  *; 
-keep class com.company.project.utils.wiremodels.ProtoFile2  *; 
-keep class com.company.project.utils.wiremodels.ProtoFile3  *; 
-keep class com.company.project.utils.wiremodels.ProtoFile4  *; 
-keep class com.company.project.utils.wiremodels.ProtoFile5  *; 
-dontwarn com.google.**
-keepattributes Signature
-keepattributes *Annotation*
-keepattributes Exceptions
-dontwarn org.w3c.dom.bootstrap.DOMImplementationRegistry
-dontwarn org.simpleframework.xml.stream.**

如果我能在这方面得到一些帮助,那就太棒了,如果我应该提供更多信息,请告诉我。

编辑:在标记答案的 cmets 中回答的问题(供将来参考)

【问题讨论】:

【参考方案1】:

你可以在某些类中保留方法:

-keepclassmembers,allowobfuscation class com.company.project.yourClass.** 
    <methods>;

当您使用wire 时,建议使用these indications proguard 格式:

-keep class com.squareup.wire.**  *; 
-keep class com.yourcompany.yourgeneratedcode.**  *; 

如果问题来自retrofit here is a proguard example:

-keep class com.squareup.okhttp.**  *; 
-keep class retrofit.**  *; 
-keep interface com.squareup.okhttp.**  *; 

-dontwarn com.squareup.okhttp.**
-dontwarn okio.**
-dontwarn retrofit.**
-dontwarn rx.**

-keepclasseswithmembers class * 
    @retrofit.http.* <methods>;


# If in your rest service interface you use methods with Callback argument.
-keepattributes Exceptions

# If your rest service methods throw custom exceptions, because you've defined an ErrorHandler.
-keepattributes Signature

【讨论】:

有没有我可以用它来防止NoSuchMethodException?日志不够具体,无法知道正在寻找什么方法 将它添加到你的 proguard 文件中,类名包含恼人的方法,看看它是否有帮助 叹息,没有运气......我得到的下一个错误是java.lang.IllegalArgumentException: Unable to create converter for class com.company.project.d.a.h(认为它指的是改造的电线响应转换器) 您是否尝试添加github.com/square/wire#generating-code-with-wire 中提到的-keep class com.squareup.wire.** *; -keep class com.yourcompany.yourgeneratedcode.** *; 是的,它确实有效(而不是像我在问题中那样让 proguard 保留每个单独生成的文件)。但是还有一个涉及 SimpleXML 和 Proguard 的问题。我想在进行更多研究后,我会为此提出另一个 SO 问题。

以上是关于Proguard for Wire + Retrofit NoSuchMethodException的主要内容,如果未能解决你的问题,请参考以下文章

markdown retro.md

air jordan 13 retro 2017 reviews and story

javascript bootstrap_retro_prepworx.js

ProGuard for Android 和 Retrofit2 Converter Gson?

如何在 gradle for Android 项目中更改 proguard 映射文件名

Air Jordan 8 Retro Performance Review