App Center 崩溃 (React Native)

每次应用崩溃时,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 只能在测试/测试版应用中使用,不会在生产应用中执行任何操作。

Crashes.generateTestCrash();

还可以轻松地生成 JavaScript 崩溃。 将以下行添加到代码,这会引发 JavaScript 错误并导致崩溃。

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

提示

若要将此崩溃发送到 App Center,需要在 发布模式下 编译 React Native 应用。

备注

目前,App Center 不支持将源映射用于 Android React Native 应用的 unminify JavaScript 堆栈跟踪。

备注

为了避免 throw throw 'message' 在这种情况下React Native 不会保留完整的 javascript 堆栈,使用字符串值 (例如:) 的 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 发送崩溃日志之前和时执行其他操作。

在 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 函数,请改为返回履行承诺。 下面的示例以异步方式将文本和图像附加到崩溃:

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

Breakpad

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 再次崩溃,请使用相同的 API,但将 true 作为参数传递。

await Crashes.setEnabled(true);

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

检查是否已启用 App Center 崩溃

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

const enabled = await Crashes.isEnabled();