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

Abb*_*bas 7 android proguard xml-deserialization android-proguard 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
Run Code Online (Sandbox Code Playgroud)

A类没有/ default构造函数应该可以工作.我还添加了一个No Argument Constructor.但这并没有纠正这个问题.

@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
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,没有构造函数(添加默认的空构造函数可以解决问题).所以默认的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;
}
Run Code Online (Sandbox Code Playgroud)

但是如果我想这样做,我有太多的文件需要改变.除了需要映射所有值的构造函数之外,不需要.我有很多类,它们托管了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>(...);
}
Run Code Online (Sandbox Code Playgroud)

值得注意的是,在此错误之前我得到了

E/ERROR: java.lang.RuntimeException: org.simpleframework.xml.core.ElementException: Element 'version' does not have a match in class A at line 1
Run Code Online (Sandbox Code Playgroud)

通过在@ElementAnnotation中添加'name'参数解决了这个问题.因此,我不愿意更改所有文件的原因之一是,如果另一个错误出现了.

编辑1: 所以在寻找解决方案2天后,我放弃了,最后在所有类中添加了构造函数.问题是库调用构造函数只用于可用的xml标签.如果只有country_code在xml中可用,请说明上面的A类

<xml>
    <data>
        <country_code>PK</country_code>
    </data>
</xml>
Run Code Online (Sandbox Code Playgroud)

然后我需要一个只有一个country_code参数的构造函数才能使它工作

public A(@Element(name = "country_code") String country_code) {
    this.country_code = country_code;
}
Run Code Online (Sandbox Code Playgroud)

这使得找到的解决方案无法使用.

编辑2: 找到了解决方法!将POJO类保留在proguard规则中可以修复此错误.但我宁愿不保留这些课程.

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

Ric*_*rdo 2

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

## 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.* *;
}
Run Code Online (Sandbox Code Playgroud)