App Center 崩溃 (React Native)

重要

Visual Studio App Center 计划于 2025 年 3 月 31 日停用。 虽然可以继续使用 Visual Studio App Center,直到它完全停用,但你可以考虑迁移到几个建议的替代方法。

详细了解支持时间线和替代方案。

每次应用崩溃时,App Center 崩溃都会自动生成崩溃日志。 日志首先写入设备的存储,当用户再次启动应用时,故障报告将发送到 App Center。 收集崩溃适用于 beta 和实时应用,即提交到 Google Play 的应用。 崩溃日志包含有价值的信息,可帮助你修复故障。

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

无论在何处使用 App Center 崩溃,请在文件顶部添加以下导入。

// 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 'message') )的 JavaScript throw 语句,因为在此方案中,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,这非常有用。 一些开发人员选择显示其他 UI 以向用户道歉,或者希望在崩溃发生后取得联系。

有关上次崩溃的详细信息

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

const crashReport = await Crashes.lastSessionCrashReport();

自定义 App Center 崩溃的用法

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.
});

所有回调都是可选的。 无需在事件侦听器对象中提供所有 3 种方法,例如,只能实现 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 async/await 函数,请改为返回已实现的 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 中断板崩溃。

按照上述常规设置步骤,在替代OnCreate中添加MainActivity.java小型转储配置,并调用用于设置 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 崩溃,请使用同一 API,但将 作为参数传递 true

await Crashes.setEnabled(true);

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

检查是否启用了 App Center 崩溃

还可以检查是否启用 App Center 崩溃:

const enabled = await Crashes.isEnabled();