Proguard - PersistenceException:构造函数与类不匹配
Posted
技术标签:
【中文标题】Proguard - PersistenceException:构造函数与类不匹配【英文标题】:Proguard - PersistenceException: Constructor not matched for class 【发布时间】:2018-05-04 14:11:42 【问题描述】:我在我的应用程序中使用retrofit2.0
和simpleframework.xml
库。
问题是当我在没有 proguard 的情况下运行应用程序时,它可以正常工作,但是当我运行 proguard 时,我在日志中收到以下错误。
E/ERROR: java.lang.RuntimeException: org.simpleframework.xml.core.PersistenceException: Constructor not matched for class A
A 类没有应该工作的/默认构造函数。我仍然添加了一个 No Argument Constructor。但这并没有解决问题。
A类
@Root(name = "data",strict = false)
public class A
@Element(name = "baseurl",required = false)
private String baseURl;
@Element(name = "country_code")
private String country_code;
// Setters and getters
如您所见,没有构造函数(添加默认的空构造函数会保留问题)。所以默认的 No Argument Constructor 应该也能正常工作。但是我尝试使用以下构造函数,这消除了错误。
public A(@ELement(name = "baseurl") String baseUrl,
@Element(name = "country_code") String country_code) // Add all the elements from the xml in the constructor i.e. if a new element is added a new constructor would have to be written.
baseURl = baseUrl;
this.country_code = country_code;
但是如果我想这样做,我有太多文件要更改。除了需要所有映射的值的构造函数之外,不应该是必需的。我有很多类包含 50 多个成员变量(我将示例类简化为仅包含两个成员变量)。这个类包含大约 30 个,代码太长了,不能在这里发布。
问题是我有很多类在假设每个类都没有参数构造函数。
简单地为所有人添加构造函数是不可行的。
我的 proguard-rules.pro(只有相关的 lib 混淆规则)。
#-keepattributes *Annotation*
-dontwarn retrofit2.**
-keep class retrofit2.** *;
-dontwarn com.bea.xml.stream.**
-dontwarn org.simpleframework.xml.stream.**
-keep class org.simpleframework.xml.** *;
-keepclassmembers,allowobfuscation class *
@org.simpleframework.xml.* <fields>;
@org.simpleframework.xml.* <init>(...);
可能值得注意的是,在此错误之前我得到了
E/ERROR: java.lang.RuntimeException: org.simpleframework.xml.core.ElementException: Element 'version' does not have a match in class A at line 1
通过在 @Element
注释中添加“名称”参数解决了这个问题。因此,我不愿意更改所有文件的原因之一是如果出现另一个错误怎么办。
编辑 1: 因此,在寻找解决方案 2 天后,我放弃了,最后为所有类添加了构造函数。问题是库只为可用的 xml-tags 调用构造函数。如果在 xml 中只有 country_code 可用,则说上述 A 类
<xml>
<data>
<country_code>PK</country_code>
</data>
</xml>
然后我需要一个只有一个 country_code 参数的构造函数才能使其工作
public A(@Element(name = "country_code") String country_code)
this.country_code = country_code;
这使得找到的解决方案无法使用。
编辑 2: 找到了解决方法!将 POJO 类保留在 proguard 规则中可修复此错误。但我宁愿不保留这些课程。
因此,我至少暂时或直到有人能告诉我为什么要保留这些文件为止。
【问题讨论】:
我也遇到同样的问题,无法解决 你能分享你的整个xml吗?我可以检查一下。 如果您的应用程序在没有 proguard 和发布版本的情况下工作,您也可以更新 只要未启用 proguard,应用程序就可以正常工作。顺便说一句,我找到了一个我不喜欢的解决方案:保留所有 POJO 对象(在 proguard 中)。我真的不喜欢!我仍然愿意在不保留所有这些类的情况下解决这个问题。 @rajlaxmi_jagdale 查看更新。 【参考方案1】:我猜你的问题是你没有保留任何属性,这显然取决于你使用的属性。就我而言,这就是我处理它的方式,让我知道它是否适合您:
## https://square.github.io/retrofit/ ##
-dontwarn retrofit2.**
-keep class retrofit2.** *;
-keepattributes Signature
-keepattributes Exceptions
-keepclasseswithmembers class *
@retrofit2.http.* <methods>;
## Simple XML ##
-dontwarn org.simpleframework.xml.stream.**
-keep public class org.simpleframework.** *;
-keep class org.simpleframework.xml.** *;
-keep class org.simpleframework.xml.core.** *;
-keep class org.simpleframework.xml.util.** *;
-keepattributes ElementList, Root, *Annotation*
-keepclassmembers class *
@org.simpleframework.xml.* *;
【讨论】:
不起作用,日志中仍然出现相同的异常。顺便说一句,没有必要继续改造2。 你是否也保留了 Exceptions 属性?【参考方案2】:尝试在您的 proguard 文件中添加以下这些行。它应该可以解决您的问题
-dontnote retrofit2.Platform
-keepattributes Signature
-keepattributes Exceptions
并删除以下这些行
-dontwarn retrofit2.**
-keep class retrofit2.** *;
【讨论】:
@abbas 你能检查一下吗?以上是关于Proguard - PersistenceException:构造函数与类不匹配的主要内容,如果未能解决你的问题,请参考以下文章
proguard.ParseException:proguard.cfg 中的未知选项“-encryptstrings”