我在使用Proguard和一些库的Android项目上遇到了一些麻烦。具体来说,我有一个XmlPullParser碰撞,无论我做什么,我似乎无法解决它。这是我正在使用的库:
JacksonParser,包括:
XStream,包括:
还有其他人,但他们不是问题。这些似乎是我们问题的罪魁祸首。
具体来说,问题是:
优化
如果我进行优化,我会“转换为dalvik失败1”。在"Conversion to Dalvik format failed with error 1" on external JAR有一篇专门针对此的帖子,它指出了重复的XmlPullParser类的方向。这是有道理的,因为XStream使用app3_min-1.1.4c.jar,其中包含一个XmlPullParser,它具有比android.jar中包含的功能更好/更多的功能。因此,我尝试从android.jar中删除通配符xmlpull **:
-libraryjars <java.home>/lib/rt.jar;C:/Android/platforms/android-9/android.jar(!org/xmlpull/v1/**)
我也尝试过明确删除它们:
-libraryjars <java.home>/lib/rt.jar;C:/Android/platforms/android-9/android.jar(!org/xmlpull/v1/XmlPullParser.class,!org/xmlpull/v1/XmlPullParserException.class,!org/xmlpull/v1/XmlPullParserFactory,!org/xmlpull/mxp1/MXParser)
但这两种方法都没有帮助。
但等等,还有更多(所有问题都集中在同一个问题上,所以我想如果我解决了这个问题,那么其他问题就会消失)。
模糊处理
如果我尝试混淆,我会收到以下运行时错误:
java.lang.NoSuchMethodError: android.content.res.XmlResourceParser.s
looking this up in the mapping, i get: .s = abstract int next()
所以它缺少next()方法。那么为什么这种方法丢失了?我不明白。我甚至试过这样做:
-keep class android.content.res.XmlResourceParser { int next(); }
确保方法得到保留,但我仍然遇到同样的问题。
收缩
萎缩似乎也失败了。应用程序启动但永远不会到达任何地方,它只是不断尝试反复启动第一个活动并给我一个无用的错误。我对此并不那么担心,如果我可以进行模糊处理和优化工作,我可以在不缩小的情况下生活。
更多信息
作为参考,我试图以两种方式引用我的库,第一种是使用冲突:
-injars ReferencedAssemblies/XStream/xpp3_min-1.1.4c.jar(!META-INF/MANIFEST.MF)
-injars ReferencedAssemblies/JacksonParser/jackson-all-1.6.4.jar(!META-INF/MANIFEST.MF,!META-INF/ASL2.0,!META-INF/LICENSE,!META-INF/NOTICE)
-injars ReferencedAssemblies/JacksonParser/joda-time-1.6.2.jar(!META-INF/MANIFEST.MF)
-injars ReferencedAssemblies/JacksonParser/jsr311-api-1.0.jar(!META-INF/MANIFEST.MF)
-injars ReferencedAssemblies/JacksonParser/stax2-api-3.0.0.jar(!META-INF/MANIFEST.MF)
-injars ReferencedAssemblies/XStream/xstream-for-android-1.0.0.jar(!META-INF/MANIFEST.MF)
这甚至不会构建。
我也这样做了:
-libraryjars <java.home>/lib/rt.jar
;C:/Android/platforms/android-9/android.jar(!org/xmlpull/v1/**)
#;C:/Android/platforms/android-9/android.jar(!org/xmlpull/v1/XmlPullParser.class,!org/xmlpull/v1/XmlPullParserException.class,!org/xmlpull/v1/XmlPullParserFactory,!org/xmlpull/mxp1/MXParser)
;ReferencedAssemblies/JacksonParser/jackson-all-1.6.4.jar(!META-INF/MANIFEST.MF,!META-INF/ASL2.0,!META-INF/LICENSE,!META-INF/NOTICE)
;ReferencedAssemblies/JacksonParser/joda-time-1.6.2.jar(!META-INF/MANIFEST.MF)
;ReferencedAssemblies/JacksonParser/jsr311-api-1.0.jar(!META-INF/MANIFEST.MF)
;ReferencedAssemblies/JacksonParser/stax2-api-3.0.0.jar(!META-INF/MANIFEST.MF)
;ReferencedAssemblies/XStream/xpp3_min-1.1.4c.jar(!META-INF/MANIFEST.MF)
这让我最远,如果我不优化,我可以导出APK。
我也这样做了:
-dontwarn org.xmlpull.v1.**
因为这似乎是一个已知问题(见前面的链接)
任何人都知道这里发生了什么或我如何解决它?我有一种感觉,这与我使用XStream和JacksonParser的事实有关,也许其中一个JacksonParser库中也有一个XmlPullParser?问题是,这可以解释优化错误,但不能解释混淆错误。我不知道那个。为什么不找到那个方法,甚至如果我明确地保留了它?
谢谢大家。
答案 0 :(得分:8)
这对我有用:
-dontwarn org.xmlpull.v1.**
-dontnote org.xmlpull.v1.**
-keep class org.xmlpull.** { *; }
答案 1 :(得分:1)
您的ProGuard配置和构建过程似乎混淆了程序罐和库罐。
对于ProGuard,您可以将所有列出的jar指定为输入jar(使用-injars)。他们的处理版本将最终出现在输出jar中(-outjars)。
你可以通过将它们从android.jar中过滤掉来避免关于重复xmlpull类的警告。如果输入罐中有任何重复,ProGuard也会打印出警告。然后,您也可以过滤掉这些重复项。
您不应将<java.home>/lib/rt.jar
指定为库jar,因为此jar也不作为Android设备上的库存在。一些列出的罐子依赖于它,因此至少部分罐子与Android运行时不完全兼容。避免关于违规类的警告的最干净的解决方案是将它们从相应的输入罐中过滤掉(例如过滤器!com/thoughtworks/xstream/converters/extended/ColorConverter.class
)。或者,您可以直截了当地关闭这些警告(例如-dontwarn com.thoughtworks.xstream.converters.extended.ColorConverter
)。
对于Dalvik编译器,您应该只指定已处理的输出jar,而不是任何进入它的程序jar。否则,您将获得重复的类:一些未处理的副本和一些部分模糊的副本。它们不会混合并导致Error1和NoSuchMethodErrors。
答案 2 :(得分:0)
要让库类优先并关闭Proguard,请将它放在main-rules.xml中(但首先将部件复制到build.xml):
-libraryjars ${android.libraryjars}(!org/xmlpull/v1/XmlPullParser.class,!org/xmlpull/v1/XmlPullParserException.class)
您也会遇到XStream的其他问题,请参阅: Proguard and XStream with omitField() on Android
对于整个故事:https://plus.google.com/112617873637231221858/posts/YxWrEJRMSo4
答案 3 :(得分:0)
XML解析在Android上可能是一个真正的痛苦。我最近在尝试在Android上使用Jackson XML数据绑定时遇到了类似的问题。
我最终使用Jar Jar Links工具将我试图使用的库中的冲突类移动到一个与Android平台类不冲突的新包名:
http://code.google.com/p/jarjar/
你可以告诉Jar Jar Links在我们提供的与Android冲突的XML库JAR文件中找到命名空间(即javax.xml.stream.*
),并让JarJar将它们重命名为不冲突的东西(即,edu.usf.cutr.javax.xml.stream.*
)。然后Android将接受没有Conversion to Dalvik format failed with error 1
的冲突库。
这是一个zip file,其中包含我用来批量转换我需要的XML库的文件,其中包括:
包含generate_android_jarsv21.bat
批处理文件,可以同时使用JarJar为多个XML库JAR自动执行转换过程。
JarJar使用一系列规则来更改JAR文件中的命名空间。以下是我的rules.txt文件的内容,该文件将javax.xml.stream.*
的所有出现重命名为edu.usf.cutr.javax.xml.stream.*
:
rule javax.xml.stream.** edu.usf.cutr.javax.xml.stream.@1
您应该能够对您正在使用的XML库执行类似的过程。通过将库类移动到新包来解决包中的冲突后,Proguard的其他下游问题应该自行解决。
我在这里写了一个完整的教程,其中包含了“修改Android版XML库”的更多细节:
https://github.com/CUTR-at-USF/SiriRestClient/wiki/Modifying-XML-libraries-for-Android