Proguard混淆导致dex编译抛出异常

7

我有一个Android应用程序,我只想使用Proguard混淆它(因此,我有-dontoptimize -dontshrink -dontpreverify标志)。当我使用Proguard构建时,Proguard本身不会抛出任何错误,但然后dex会抛出以下异常:

Exception in thread "pool-1-thread-1" com.android.dx.cf.code.SimException: com.android.dx.rop.cst.CstMethodRef cannot be cast to com.android.dx.rop.cst.CstInterfaceMethodRef
at com.android.dx.cf.code.BytecodeArray.parseInstruction(BytecodeArray.java:810)
... 
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassCastException: com.android.dx.rop.cst.CstMethodRef cannot be     cast to com.android.dx.rop.cst.CstInterfaceMethodRef

应用程序立即因NullPointerException而崩溃。

我正在使用Android Studio进行构建,使用最新版本的Proguard,在默认的proguard文件和一些额外的-keep选项和-dontwarn选项上。有什么想法是什么原因导致这种情况?谢谢!


如果遇到相同的问题,请告诉我,如果找到任何解决方案。 - amodkanthe
1
我已经审查了这个问题的一个答案,结果发现它是基于一个已删除答案的审核。也许它不够好作为一个答案,但它仍然说了一些有用的东西:它说这是一个官方的 bug,可以在 Android 的 bug 追踪器 上找到。它目前的状态是 FutureRelease,甚至还有一些解决方法,比如回退到 7.8 或从 gradle 1.5.0 回退到 1.3.0,请查看更多详细信息。希望这能帮到你! - Fabio says Reinstate Monica
2个回答

1
我在Android Studio中遇到了类似的问题。当执行'dex'将外部Jar转换为dalvik时,出现了问题。
Error:Android Pre Dex: [SOX.jar]
com.android.dx.rop.cst.CstInterfaceMethodRef cannot
be cast to com.android.dx.rop.cst.CstMethodRef

然后出现了一些关于字符串处理的晦涩引用。 升级了所有内容,但无济于事。

我最终发现,调用某些次要字符串处理的方法已被放置在接口中。这对于主流Java来说很好用,但显然对于dex来说不行。当该方法从接口中移出并重新放回其中一个类中时,dex就不会出错。

我的建议是仔细检查代码,寻找dex可能无法处理的新语言特性或高级特性。我知道这并没有太大帮助,这个bug使我的Android开发停滞了2个月。


1
这不是一个答案;如果您认为有价值,可以在问题下发表评论。 - beresfordt
大家好,感谢建议留言,但由于声望不足,我无法在 OP 上发表评论。我只能回到默默无闻的状态 :) - Iang

0

如果您在Android Studio中使用java 1.8+级别API和/或:

  1. 使用不兼容的gradle配置进行构建(sourceVersion/targetVersion无效)
  2. 使用当前Android上不可用的1.8 API进行构建
  3. 您正在使用非法的类转换或反射,在dex时间之前可能无法检测到(截至本文发布时未解决)

您可以将“较旧”和“较新”的API版本替换为1.7和1.8,确切的API版本并不重要。

我建议剥离库和可疑代码,直到您获得成功的构建。在我的情况下,它是像这样转换为一个类:

Class<E> klass = (Class<E>) Class.forname(...).asSubclass(...) ... ;

这个程序编译通过了(偶尔会有警告——另一个 bug),但在 dex 时间抛出了你收到的晦涩错误。将其移除后问题得到解决。

我还注意到,将语言级别降低一个版本,然后再升回来(1.8 -> 1.7 -> 1.8),并在每次更改后应用和退出设置,会生成一组之前缺失的新警告。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接