使用 minifyEnabled 和 proguard 时如何将崩溃日志转换为可读形式?

问题描述

我的项目有以下设置:

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'
        }
    }

崩溃日志有时来自应用程序用户,例如:

l.c.b.c0.a.g
l.c.b.a0.z.j$a.a
l.c.b.i.c
l.c.b.i.b
k.a.a.f.a.i.a
n.m0.g.e$a.run
java.util.concurrent.ThreadPoolExecutor.runWorker ThreadPoolExecutor.java:1167
java.util.concurrent.ThreadPoolExecutor$Worker.run ThreadPoolExecutor.java:641
java.lang.Thread.run Thread.java:919

但是我怎么能理解这里写的内容呢?应该有反向转换。

如有任何帮助,我将不胜感激!

解决方法

要首先取回可读代码,您必须确保始终保留映射文件的副本,该副本随minifyEnabled 设置为true 的每个构建生成。请注意,每次构建时映射文件都会被覆盖,因此必须在构建后立即获取它们,否则映射将不再对应于您的目标二进制文件。

映射文件在以下位置生成:

<your-module-name>/build/outputs/mapping/<build-type>/ 

然后您可以使用位于以下位置的 ReTrace 工具:

<your-android-sdk-location>\tools\proguard\lib\proguardgui.jar

ReTrace 屏幕截图,(该工具适用于 proguard 和 R8):

enter image description here

要直接在 android 的开发者控制台中查看任何未混淆的崩溃堆栈跟踪,在完成发布新版本后,转到“App Bundle Explorer” 部分,选择“下载”,并上传对应的映射文件。看截图:

enter image description here

• 奖金

下一个 gradle 脚本会将映射文件复制到与输出构建相同的位置,因此您无需在每次发布时浏览它们:

task copyMappings() {

    android.applicationVariants.all { variant ->

        variant.outputs.all { output ->
            variant.getAssembleProvider().configure() {
                it.doLast {
                    if (variant.getBuildType().isMinifyEnabled()) {

                        def mappingProvider = variant.getMappingFileProvider()

                        if (mappingProvider != null) {

                            def files = mappingProvider.get().files

                            if (!files.isEmpty()) {

                                def mappingFile = files.iterator().next()

                                if (mappingFile != null && mappingFile.exists()) {
                                    copy {
                                        from mappingFile
                                        into variant.getPackageApplicationProvider().get().outputDirectory
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}