App Center 崩溃(React Native)

重要

Visual Studio App Center 于 2025 年 3 月 31 日停用,但分析和诊断功能除外,这些功能将继续受支持,直到 2026 年 6 月 30 日。 了解详细信息

每次应用发生崩溃时,App Center Crashes 功能都会自动生成一份崩溃日志。 日志首先写入设备的存储,当用户再次启动应用时,崩溃报告将发送到 App Center。 收集崩溃报告适用于 beta 版本和已上线的应用,即那些已提交到 Google Play 的应用。 故障日志包含有助于修复崩溃的重要信息。

如果尚未在应用程序中设置 SDK,请按照 “入门 ”部分进行作。

无论在何处使用 App Center Crashes 模块,请在文件开头添加以下导入语句。

// Import App Center Crashes at the top of the file.
import Crashes from 'appcenter-crashes';

触发测试崩溃

App Center 的崩溃模块提供了一个 API,用于生成测试崩溃,以方便测试 SDK。 此 API 只能在测试/beta 应用中使用,并且不会在生产应用中执行任何作。

Crashes.generateTestCrash();

要生成 JavaScript 崩溃也很容易。 将以下行添加到代码中,这会引发 JavaScript 错误并导致崩溃。

throw new Error('This is a test javascript crash!');

小窍门

你的 React Native 应用需要以发布模式编译,这样才能将此崩溃发送到 App Center。

注释

目前,App Center 不支持源映射来解缩 Android React Native 应用的 JavaScript 堆栈跟踪。

注释

最佳实践是避免使用字符串值(例如:throw)的 JavaScript throw 'message' 语句,因为在这种情况下,React Native 不会保留完整的 JavaScript 堆栈。 相反, throw JavaScript Error (例如: throw Error('message')) 。

获取有关以前崩溃的详细信息

App Center 崩溃功能提供两个 API,当应用程序崩溃时为您提供更多信息。

应用在上一个会话中是否收到内存不足的警告?

启动 SDK 后,可以随时检查应用是否在上一会话中收到内存警告:

const hadLowMemoryWarning = await Crashes.hasReceivedMemoryWarningInLastSession();

注释

在某些情况下,内存不足的设备可能无法发送事件。

应用在上一个会话中是否崩溃?

启动 SDK 后,可以随时检查应用是否在上一次启动中崩溃:

const didCrash = await Crashes.hasCrashedInLastSession();

如果想要在发生崩溃后调整应用的行为或 UI,这非常有用。 一些开发人员选择显示额外的用户界面来向用户道歉,或者希望在应用崩溃后找到一种与用户联系的方法。

有关上次崩溃的详细信息

如果应用之前崩溃,可以获取有关上次崩溃的详细信息。

const crashReport = await Crashes.lastSessionCrashReport();

自定义 App Center 崩溃功能的使用

App Center 崩溃为开发人员提供回调,以便在崩溃日志发送到 App Center 之前和时执行其他操作。

JavaScript 中的处理崩溃

若要使 Crash.setListener 方法按预期工作,需要检查应用程序是否已正确配置。

  1. 打开项目的ios/YourAppName/AppDelegate.m文件,并验证你是否有[AppCenterReactNativeCrashes register];而不是[AppCenterReactNativeCrashes registerWithAutomaticProcessing];
  2. 打开项目的 android/app/src/main/res/values/strings.xml 文件并验证是否已 appCenterCrashes_whenToSendCrashes 设置为 ASK_JAVASCRIPT

此文档中逐个讨论事件侦听器的所有不同回调,但需要设置一个事件侦听器,用于同时定义所有回调。

是否应处理故障?

如果您希望决定某个特定崩溃是否需要处理,请实现此回调。 例如,系统级崩溃您可能希望忽略,并且您不想发送到 App Center。

Crashes.setListener({

    shouldProcess: function (report) {
        return true; // return true if the crash report should be processed, otherwise false.
    },

    // Other callbacks must also be defined at the same time if used.
    // Default values are used if a method with return parameter isn't defined.
});

注释

若要使用此功能,需要为故障服务正确配置应用程序。

此功能取决于 JavaScript 的崩溃处理

如果用户隐私对你很重要,则应在将崩溃报告发送到 App Center 之前收到用户确认。 SDK 公开了一个回调接口,指示 App Center 崩溃在发送崩溃报告之前等待用户确认。

如果选择这样做,则需负责获取用户的确认,例如,通过具有以下选项之一的对话框提示: 始终发送发送不发送。 根据提供的输入,你将告知 App Center 崩溃要执行什么操作,然后会相应地处理崩溃。

注释

SDK 不为此显示对话框,应用必须提供自己的 UI 才能请求用户同意。

以下回调演示如何告知 SDK 在发送崩溃之前等待用户确认:

Crashes.setListener({

    shouldAwaitUserConfirmation: function (report) {

        // Build your own UI to ask for user consent here. SDK doesn't provide one by default.

        // Return true if you built a UI for user consent and are waiting for user input on that custom UI, otherwise false.
        return true;
    },

    // Other callbacks must also be defined at the same time if used.
    // Default values are used if a method with return parameter isn't defined.
});

如果 true 返回,您的应用必须使用自己的代码来获取用户的许可,并使用以下 API 将结果更新到 SDK 中。

import Crashes, { UserConfirmation } from 'appcenter-crashes';

// Depending on the user's choice, call Crashes.notifyUserConfirmation() with the right value.
Crashes.notifyUserConfirmation(UserConfirmation.DONT_SEND);
Crashes.notifyUserConfirmation(UserConfirmation.SEND);
Crashes.notifyUserConfirmation(UserConfirmation.ALWAYS_SEND);

注释

若要使用此功能,请为故障服务正确配置应用程序。 此功能取决于 处理 JavaScript 中的崩溃

获取有关故障日志的发送状态的信息

有时,你想知道应用崩溃的状态。 常见的用例是,你可能想要显示 UI,告知用户你的应用正在提交崩溃报告,或者,如果应用在启动后快速崩溃,你想要调整应用的行为,以确保可以提交崩溃日志。 App Center 崩溃有三个不同的回调,你可以在应用中使用它来通知发生了什么情况。

为此,请在代码中定义事件侦听器,如以下示例所示:

Crashes.setListener({
    onBeforeSending: function (report) {
        // called after Crashes.process and before sending the crash.
    },
    onSendingSucceeded: function (report) {
        // called when crash report sent successfully.
    },
    onSendingFailed: function (report) {
        // called when crash report couldn't be sent.
    }

    // Other callbacks must also be defined at the same time if used.
    // Default values are used if a method with return parameter isn't defined.
});

所有回调都是可选的。 您无需在事件侦听器对象中实现所有三种方法,例如,您可以只实现onBeforeSending

注释

若要使用此功能,需要为故障服务正确配置应用程序。

此功能取决于 JavaScript 的崩溃处理

注释

如果Crashes.setListener多次调用,最终生效的是最后一个调用;它将覆盖以前通过Crashes.setListener设置的侦听器。

接收 onSendingFailed 意味着发生不可恢复的错误,例如 4xx 代码。 例如, 401 表示 appSecret 错误。

如果是网络问题,此回调不会被触发。 在这种情况下,SDK 会不断重试(并在网络连接关闭时暂停重试)。 如果我们在终端发生网络问题或服务中断的情况下重启应用程序,那么在 onBeforeSending 进程重启后,应用程序将再次被触发。

将附件添加到崩溃报告

可以将二进制附件和文本附件添加到崩溃报告。 SDK 会随崩溃一起发送它们,以便在 App Center 门户中看到它们。 在发送以前应用程序启动时存储的崩溃信息之前,将调用以下回调函数。 崩溃发生时不会调用它。 请确保附件文件 命名 minidump.dmp 为为小型转储文件保留该名称。 下面是如何将文本和图像附加到故障的示例:

import Crashes, { ErrorAttachmentLog } from 'appcenter-crashes';

Crashes.setListener({
    getErrorAttachments(report) {
        const textAttachment = ErrorAttachmentLog.attachmentWithText('Hello text attachment!', 'hello.txt');
        const binaryAttachment = ErrorAttachmentLog.attachmentWithBinary(`${imageAsBase64string}`, 'logo.png', 'image/png');
        return [textAttachment, binaryAttachment];
    }

    // Other callbacks must also be defined at the same time if used.
    // Default values are used if a method with return parameter isn't defined.
});

参数 fileName 是可选的(可以 null),仅在 App Center 门户中使用。 在门户中发生特定崩溃事件时,您可以查看附件并下载。 如果指定了文件名,则为要下载的文件名,否则会为你生成文件名。

若要设置 getErrorAttachments 回调以使用 ES2017 异步/等待 函数,请改为返回已经实现的 Promise。 以下示例展示如何以异步方式将文本和图像附加到软件崩溃报告中:

import Crashes, { ErrorAttachmentLog } from 'appcenter-crashes';

Crashes.setListener({
    getErrorAttachments(report) {
        return (async () => {
            const textContent = await readTextFileAsync(); // use your async function to read text file
            const binaryContent = await readBinaryFileAsync(); // use your async function to read binary file
            const textAttachment = ErrorAttachmentLog.attachmentWithText(textContent, 'hello.txt');
            const binaryAttachment = ErrorAttachmentLog.attachmentWithBinary(binaryContent, 'logo.png', 'image/png');
            return [textAttachment, binaryAttachment];
        })();
    }

    // Other callbacks must also be defined at the same time if used.
    // Default values are used if a method with return parameter isn't defined.
});

注释

若要使用此功能,需要为故障服务正确配置应用程序。

此功能取决于 JavaScript 的崩溃处理

注释

Android 上的大小限制当前为 1.4 MB,iOS 大小限制为 7 MB。 尝试发送更大的附件将触发错误。

已处理的错误

App Center 还允许你通过 trackError 方法使用处理异常来跟踪错误。 应用可以选择将属性或/和附件附加到已处理的错误报告,以提供进一步的上下文。

try {
    // Throw error.
} catch (error) {

    // Prepare properties.
    const properties = { 'Category' : 'Music', 'Wifi' : 'On' };

    // Prepare attachments.
    const textAttachment = ErrorAttachmentLog.attachmentWithText('Hello text attachment!', 'hello.txt');
    const attachments = [textAttachment];

    // Create an exception model from error.
    const exceptionModel1 = ExceptionModel.createFromError(error);

    // ..or generate with your own error data.
    const exceptionModel2 = ExceptionModel.createFromTypeAndMessage("type", "message", "stacktrace");

    // Track error with custom data.
    Crashes.trackError(exceptionModel1, properties, attachments);
    Crashes.trackError(exceptionModel1, properties, nil);
    Crashes.trackError(exceptionModel2, nil, attachments);
    Crashes.trackError(exceptionModel2, nil, nil);
}

断板

App Center 支持 React Native 应用中的 Android NDK Breakpad 崩溃。

按照上述常规设置步骤进行操作,然后重写MainActivity.java以覆盖OnCreate,添加小型转储配置,并调用设置 Breakpad 配置的本机代码。

示例:

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Crashes.getMinidumpDirectory().thenAccept(new AppCenterConsumer<String>() {
      @Override
      public void accept(String path) {
        // Path is null when Crashes is disabled.
        if (path != null) {
          // links to NDK
          setupBreakpadListener(path);
        }
      }
    });
  }

在运行时启用或禁用 App Center 崩溃功能

可以在运行时启用或禁用 App Center 崩溃功能。 如果禁用它,SDK 不会针对应用执行任何崩溃报告。

await Crashes.setEnabled(false);

若要再次启用 App Center Crashes,请使用相同的 API,但将 true 作为参数传递。

await Crashes.setEnabled(true);

状态在应用程序启动时保留在设备的存储中。

检查是否启用了 App Center 崩溃功能

您还可以检查 App Center 的崩溃报告功能是否已启用:

const enabled = await Crashes.isEnabled();