首页 > 解决方案 > 如何使用 Android Developer Console 崩溃报告查找崩溃源?

问题描述

由于我在 Google Play 商店中发布了我的应用程序的新版本,因此我在 Android 开发者控制台中收到了崩溃报告。

mappings.txt在发布新版本后立即上传了 ProGuard。因此,所有日志都没有被混淆(所有类名和方法都以明文形式出现)。但是,我仍然不确定是否愿意阅读它们。

存在三个主要问题:

  1. 该报告仅显示崩溃方法,但不显示行号。所以我不知道方法的哪一部分导致了崩溃。
  2. 一些崩溃报告显示了使用OR. 这是什么意思?
  3. 并非所有报告都经过去混淆处理。有些仍然显示为匿名类和方法名

例子:

// Crash Log with is NOT obfuscated
Caused by: java.lang.NullPointerException: 
1:  at com.example.MyApp.Path.To.Package.MyClass.myMethod1 (MyClass.java)  // <-- No Line Numbers...
    or                     .myMethod2 (MyClass.java)    // <-- WHAT does this OR mean???
    or                     .myMethod3 (MyClass.java)
2:  at com.example.MyApp.Path.To.Package.MyClass.onCreateView (MyClass.java)
3:  at android.support.v4.app.Fragment.performCreateView (Fragment.java)
4:  at android.support.v4.app.FragmentManagerImpl.access$500 (FragmentManagerImpl.java)
    or                     .access$600 (FragmentManagerImpl.java)
    or                     .addFragment (FragmentManagerImpl.java)
    or                     .allocBackStackIndex (FragmentManagerImpl.java)
    or                     .animateRemoveFragment (FragmentManagerImpl.java)
    ...

5:  at android.support.v4.app.FragmentManagerImpl.access$500 (FragmentManagerImpl.java)
...


// Other crash seems to show the same problem but is still obfuscated
Caused by: java.lang.NullPointerException: 
1:  at com.example.MyApp.Path.To.Package.MyClass.a (MyClass.java:89)  // <-- Line numbers available here...
2:  at com.example.MyApp.Path.To.Package.MyClass.b (MyClass.java:40)
3:  at android.support.v4.app.Fragment.performCreateView (Fragment.java)
... // Same call stack as above  

问题:

所以主要问题是:

如何使用日志中的信息来查找崩溃的根源?

标签: androidcrash-reportscallstack

解决方案


您需要在 Proguard 配置中添加以下选项:

# This option forces Proguard to use different obfuscated names
# for different members. It avoids the 'or' stack traces.
-useuniqueclassmembernames

# These options produce useful stacktraces preserving line numbers
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

如果没有-useuniqueclassmembernames,Proguard 可以为来自同一类的不同方法分配相同的混淆名称(您可以在 mapping.txt 文件中看到它)。这就是为什么堆栈跟踪知道错误发生在方法 A方法 B 中,但不知道究竟是哪一个。

使用该-useuniqueclassmembernames选项,所有混淆的名称都将不同,并且不会有更多堆栈跟踪。更多关于这里的信息。

除此之外,Proguard 不会保留有关行号的信息,除非我们按照指示使用-renamesourcefileattributeand选项。-keepattributes更多关于这里的信息。

这些选项会稍微增加您的 apk 大小,但这是完全值得的。这让我在分析堆栈跟踪时遇到了很多麻烦。


推荐阅读