Proguard - PersistenceException:构造函数与类不匹配

时间:2017-11-21 07:33:21

标签: android proguard android-proguard xml-deserialization simple-xml-converter

我在我的应用中使用retrofit2.0 simpleframework.xml库。

问题是当我在没有proguard的情况下运行应用程序时它工作正常但是当我运行proguard时,我在日志中遇到以下错误。

E/ERROR: java.lang.RuntimeException: org.simpleframework.xml.core.PersistenceException: Constructor not matched for class A

A类没有/ default构造函数应该可以工作。我仍然添加了 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
}

正如您所看到的,没有构造函数(添加默认的空构造函数可以解决问题)。因此,默认无参数构造函数也应该可以正常工作。但是,我尝试使用以下构造函数,这将删除错误。

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个,代码在这里发布的时间太长了。

问题是我有很多类在为每个类假设No Argument构造函数的情况下工作。

简单地为所有人添加构造函数是不可行的。

我的 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注释中添加'name'参数解决了这个问题。因此,我不愿意更改所有文件的原因之一是,如果另一个错误出现了。

编辑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规则中可以修复此错误。但我宁愿不保留这些课程。

所以我至少暂时保持这个问题,或者直到有人能告诉我为什么要保留这些文件。

2 个答案:

答案 0 :(得分:1)

我想您的问题是您没有保留任何属性,而这显然取决于您使用的属性。就我而言,这就是我的处理方式,请告知它是否对您有用:

<style name="ToolbarStyle" parent="mytheme">
    <item name="colorPrimary">@color/white</item>
    <item name="android:textColorPrimary">@android:color/white</item>
    <item name="android:textColorSecondary">@android:color/white</item>
    <item name="colorControlNormal">@android:color/white</item>
    <item name="actionMenuTextColor">@android:color/white</item>
</style>

答案 1 :(得分:0)

尝试将以下这些行添加到您的proguard文件中。它应该可以解决您的问题

-dontnote retrofit2.Platform
-keepattributes Signature
-keepattributes Exceptions

并删除以下几行

-dontwarn retrofit2.**
-keep class retrofit2.** { *; }