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规则中可以修复此错误.但我宁愿不保留这些课程.
所以我至少暂时保持这个问题,或者直到有人告诉我为什么要保留这些文件.
我想你的问题是你没有保留任何属性,这显然取决于你使用的属性。就我而言,这就是我的处理方式,请告诉我它是否适合您:
## 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)