8

Android Studio 最近开始默认使用R8而不是 ProGuard。

尽管代码被混淆了,但 ProGuard 的堆栈跟踪相当容易理解,无需使用任何工具。让我们使用以下示例:

 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
    at net.foo.anroid.Foo.wb.d(SourceFile:453)
    at net.foo.anroid.Foo.wb.a(SourceFile:213)
    at net.foo.anroid.Foo.wb.n(SourceFile:103)
    at net.foo.anroid.Foo.qa.run(Unknown Source:2)
    at java.lang.Thread.run(Thread.java:764)

通常我确切地知道 net.foo.anroid.Foo.wb 对应于哪个文件,并且行号(例如 453、213...)是 ProGuard 源文件中的实际行号。

但是,对于 R8,确定哪一行是在 mapping.txt 中查找它们的唯一方法。

这确实是一个很大的麻烦。如果没有从堆栈跟踪中快速定位源代码的好方法,我将仅出于这个原因回到 ProGuard。

有没有办法防止 R8 更改行号?

4

2 回答 2

8

R8 团队不时讨论过这个问题,我们一直在优化行号,原因有很多:

  • 它在 dex 大小上节省了 5% 的区域
  • 对于打开内联等优化的发布版本,无论如何都需要回溯来扩展内联帧
  • 它是测试矩阵中少一个选项

现在,当在配置中同时设置了 -dontoptimize(意味着没有内联)和 -dontobfuscate 时,对于调试版本和发布版本,它总是关闭的。

当您使用回溯时(请记住使用 Proguard 6 或更高版本中的那个),您不需要删除堆栈跟踪,因为回溯将通过未修改的非堆栈跟踪行。

目前应用程序中没有库可以执行此操作,因此需要将映射文件包含在应用程序中,这违背了使 apk 变小的目的。

于 2019-05-09T01:28:40.043 回答
1

在 ProGuard 配置中设置这些:

-keepattributes SourceFile,LineNumberTable

然后使用ReTrace jar

ReTrace 可以读取经过混淆的堆栈跟踪并将其还原到没有混淆的样子。恢复基于 ProGuard 在混淆过程中可以写出的映射文件。映射文件将原始类名和类成员名链接到它们的混淆名称。

java -jar retrace.jar [options...] mapping_file [stacktrace_file]

例如:

java -jar retrace.jar mapping.txt stacktrace.log
于 2019-05-07T22:18:17.810 回答