Android Studio 如何分析堆栈轨迹

前面的小节我们介绍了添加日志和查看日志,从本小节我们学习如何分析堆栈信息。

1. 应用崩溃堆栈

在应用调试过程中,当碰到应用崩溃时,最有效的分析方式是能获取到崩溃堆栈信息,通过分析堆栈信息我们可以还原现场函数调用情况,定位到崩溃的代码行。

我们特意写一段崩溃代码,然后查看下崩溃堆栈是怎样的,代码如下:

package com.imooc.firstapp;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int num = 1 / 0;
    }
}

编译运行。APP 在启动时崩溃了,从 Logcat 中看到的崩溃堆栈信息如下:

关键部分如下:

Caused by: java.lang.ArithmeticException: divide by zero
    at com.imooc.firstapp.MainActivity.onCreate(MainActivity.java:12)
    at android.app.Activity.performCreate(Activity.java:7802)
    at android.app.Activity.performCreate(Activity.java:7791)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)

从崩溃堆栈中我们可以清楚的看到是 MainActivity.java 第 12 行的 onCreate 方法中发生了崩溃,崩溃原因是 divide by zero (除数为0)。

2. 添加堆栈输出

当我们的应用因为错误或异常而崩溃时会自动输出堆栈信息外,我们还可以使用 Thread.dumpStack() 等方法输出应用代码中任意位置的堆栈轨迹。在我们分析具体业务流程时这种方法将非常有效。

我们创建一段代码,看下效果如何:

package com.imooc.firstapp;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myCall();
    }

    private void myCall() {
        Log.d("test", "myCall");
        Thread.dumpStack();
    }
}

编译运行。APP 启动时 Logcat 中的输出信息如下:

关键部分如下:

2020-06-15 16:32:56.023 15079-15079/? D/test: myCall
2020-06-15 16:32:56.023 15079-15079/? W/System.err: java.lang.Exception: Stack trace
2020-06-15 16:32:56.024 15079-15079/? W/System.err:     at java.lang.Thread.dumpStack(Thread.java:1513)
2020-06-15 16:32:56.024 15079-15079/? W/System.err:     at com.imooc.firstapp.MainActivity.myCall(MainActivity.java:18)
2020-06-15 16:32:56.024 15079-15079/? W/System.err:     at com.imooc.firstapp.MainActivity.onCreate(MainActivity.java:13)
2020-06-15 16:32:56.024 15079-15079/? W/System.err:     at android.app.Activity.performCreate(Activity.java:7802)
2020-06-15 16:32:56.024 15079-15079/? W/System.err:     at android.app.Activity.performCreate(Activity.java:7791)

从堆栈中我们可以清楚的看到是 MainActivity.java 第13行的 onCreate 方法中调用了 myCall 方法。

3. 外部来源的堆栈

有时我们需要分析错误报告中与我们分享的堆栈轨迹,而不是我们在调试时发现的堆栈轨迹。例如,我们可能正在通过 Google Play 管理中心或一些其他工具(例如 Firebase 崩溃报告)收集用户设备上生成的堆栈轨迹。

对于来自错误报告的外部堆栈轨迹,要获取相同的突出显示且可点击的视图,请按照以下步骤操作:

  1. 在 Android Studio 中打开我们的项目;

Tips:请确保我们正在查看的源代码的来源应用版本与生成堆栈轨迹的应用版本完全相同。如果代码不同,文件名与行号会不匹配,或堆栈轨迹和我们的项目中的调用顺序会不一致。

  1. Analyze 菜单中,点击 Analyze Stack Trace

  2. 将堆栈轨迹文本粘贴到 Analyze Stack Trace 窗口中,然后点击 OK

  3. Android Studio 会在 Run 窗口下打开一个新的 Stacktrace 标签页,其中包含我们粘贴的堆栈轨迹。

4. 小结

本节课程我们主要学习了如何分析堆栈信息。本节课程的重点如下:

  • 掌握如何分析崩溃堆栈;
  • 掌握如何在代码任意位置打印堆栈。