阅读 682

解决 Android 开启混淆后 Crash 信息行号对不上

前言

在 Gradle 插件版本达到 3.4.0 及以上,默认会开启 R8 进行代码优化,以往我们都是使用 SDK 自带的 proguardgui.bat 来还原堆栈信息,但在开启了 R8 混淆后这个方法就失效了,原因是 R8 内部会做各种代码优化诸如内联操作等,并实施行号映射,这时候在堆栈信息中抛出的行号就完全不是真实的崩溃位置了......

如何解决?

先来看下 release 版开启混淆后所抛出的异常信息

可以看到,我们实际是在第 45 行抛出一个 NullPointerException 的,但 Logcat 中的堆栈信息却显示在第 8 行抛出,通过 IDE 点击跳转后直接会跳到最上方导包处,也就是无法定位真实位置。

有 2 种解决方法:

  1. 自行对照混淆后生成的 mapping 文件,找出对应的真实行号,如下图,可以看到第 8 行对应着第 45 行。

  1. 下载 R8 解混淆的 jar 包,点上方的 tgz 即可开始下载,需要科学上网( android.googlesource.com/platform/pr… ),下载完成后解压到你的 Android SDK 所在位置的 lib 文件夹中,在这个文件夹中你可以看到 原有的 proguard 使用的 jar 包,防止万一,你最好备份一下将被替换的文件。当替换完成后,打开以往使用 proguardgui.bat 的文件夹,这时 proguardgui.bat 无法使用了,必须使用命令行来进行解混淆,也不复杂,步骤如下所示:

    • 新建一个 stacktrace.txt 用来复制想要解混淆的堆栈信息进去,或者你自己有 dump 出来的 stacktrace 文件也可以直接将文件丢到文件夹中。

    • 复制对应的 mapping 文件到文件夹中

    • 打开命令行并跳转到当前文件夹,输入命令 retrace.bat -verbose mapping.txt stacktrace.txt > out.txt ,按下回车后当前文件夹下会生成一个 out.txt 文件,里面存放的就是真实的堆栈信息,如下图所示。

最后

如果你还是觉得上述方法比较麻烦没有原来的好用的话,其实还有一种,就是禁用 R8 ,用回 Proguard ,在项目根目录的 gradle.properties 中写上 android.enableR8=false 即可,然后你可能会在生成 APK 时遇到如下图的报错,那就在 proguard-rules.pro 中写上 -ignorewarnings ,这样就能顺利编译了,也可以用回 proguardgui.bat 的图形化界面,前提是你有备份旧的 proguard.jar 和 retrace.jar 。

关注下面的标签,发现更多相似文章
评论