App Center (Android) 損毀

重要

Visual Studio App Center 已排定於 2025 年 3 月 31 日淘汰。 雖然您可以繼續使用 Visual Studio App Center,直到完全淘汰為止,但有數個建議的替代方案可以考慮移轉至。

深入瞭解支持時程表和替代方案。

App Center 當機會在每次應用程式當機時自動產生當機記錄。 記錄會先寫入裝置的記憶體,當使用者再次啟動應用程式時,當機報告會傳送至 App Center。 收集當機適用於 Beta 和即時應用程式,也就是提交至 Google Play 的應用程式。 當機記錄包含寶貴的資訊,可協助您修正當機。

如果您尚未在應用程式中設定 SDK,請遵循 使用者入門 一節。

產生測試當機

App Center 當機可讓您使用 API 來產生測試損毀,以便輕鬆測試 SDK。 此 API 只能用於偵錯組建,而且不會在發行組建中執行任何動作。

Crashes.generateTestCrash();
Crashes.generateTestCrash()

取得先前損毀的詳細資訊

App Center 當機有兩個 API,可讓您在應用程式損毀時提供詳細資訊。

應用程式是否在上一個會話中收到記憶體不足的警告?

在啟動 SDK 之後,您可以隨時檢查應用程式是否在上一個工作階段中收到記憶體警告:

Crashes.hasReceivedMemoryWarningInLastSession();
Crashes.hasReceivedMemoryWarningInLastSession()

此 API 是異步的,您可以在 我們的 App Center 異步 API 指南 中深入瞭解。

注意

這個方法只能在啟動之後 Crashes 使用,它一律會在開始之前傳回 false

注意

在某些情況下,記憶體不足的裝置無法傳送事件。

應用程式在上一個工作階段中是否當機?

在啟動 SDK 之後,您可以隨時檢查應用程式是否在上一次啟動時損毀:

Crashes.hasCrashedInLastSession();
Crashes.hasCrashedInLastSession()

此 API 是異步的,您可以在 我們的 App Center 異步 API 指南 中深入瞭解。

如果您想要在發生當機之後調整應用程式的行為或 UI,這會很有用。 有些開發人員選擇向用戶顯示其他UI,或想要在發生當機後連絡。

注意

這個方法只能在啟動之後 Crashes 使用,它一律會在開始之前傳回 false

上次當機的詳細數據

如果您的應用程式先前損毀,您可以取得最後一次當機的詳細數據。

Crashes.getLastSessionCrashReport();
Crashes.getLastSessionCrashReport()

此 API 是異步的,您可以在 我們的 App Center 異步 API 指南 中深入瞭解。

此 API 有許多使用案例,最常見的是呼叫此 API 並實作其自定義 CrashesListener 的人員。

注意

這個方法只能在啟動之後 Crashes 使用,它一律會在開始之前傳回 null

自訂 App Center 損毀的使用方式

App Center 當機提供回呼,讓開發人員在將當機記錄傳送至 App Center 之前和時執行其他動作。

若要處理回呼,請在 介面中 CrashesListener 實作所有方法,或覆寫 AbstractCrashesListener 類別,並只挑選您感興趣的方法。

使用您自己的 CrashesListener

建立您自己的 CrashesListener,並將其指派如下:

CrashesListener customListener = new CrashesListener() {
    // Implement all callbacks here.
};
Crashes.setListener(customListener);
val customListener = object : CrashesListener {
    // Implement all callbacks here.
}
Crashes.setListener(customListener)

如果您只想要自訂一些回呼,請改用 AbstractCrashesListener

AbstractCrashesListener customListener = new AbstractCrashesListener() {
    // Implement any callback here as required.
};
Crashes.setListener(customListener);
val customListener = object : AbstractCrashesListener() {
    // Implement any callback here as required.
}
Crashes.setListener(customListener)

注意

在呼叫 AppCenter.start()之前設定接聽程式,因為App Center會在啟動後立即開始處理當機。

是否應該處理當機?

如果您想要決定是否需要處理特定的當機,請實作此回呼。 例如,您可能想要忽略系統層級損毀,而且您不想傳送至 App Center。

@Override
public boolean shouldProcess(ErrorReport report) {
    return true; // return true if the crash report should be processed, otherwise false.
}
override fun shouldProcess(report: ErrorReport?): Boolean {
    return true
}

如果用戶隱私權對您很重要,您可能想要先取得使用者確認,再將當機報告傳送至 App Center。 SDK 會公開回呼,告知 App Center 當機以等候使用者確認,再傳送任何當機報告。

如果您選擇這樣做,您必須負責取得使用者的確認,例如透過對話框提示字元,其中包含下列其中一個選項: 一律傳送傳送不要傳送。 根據輸入,您會告訴 App Center 當機該怎麼做,然後會據以處理當機。

注意

SDK 不會顯示此對話框,應用程式必須提供自己的 UI 以要求使用者同意。

下列回呼示範如何告訴 SDK 等待使用者確認,再傳送當機:

@Override
public boolean shouldAwaitUserConfirmation() {

    // 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;
}
override fun shouldAwaitUserConfirmation(): Boolean {
    return true
}

如果您傳回 true,您的應用程式必須使用您自己的程式代碼 () 使用者的許可權,並使用下列 API 向 SDK 訊息:

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

例如,您可以參考 我們的自定義對話範例

取得當機記錄的傳送狀態相關信息

有時候,您想要知道應用程式當機的狀態。 常見的使用案例是您可能想要顯示UI,告知使用者您的應用程式正在提交當機報告,或者,如果您的app在啟動後快速當機,您想要調整應用程式的行為,以確保可以提交當機記錄。 App Center 當機有三個不同的回呼,您可以在應用程式中使用,以收到發生情況的通知:

SDK 傳送當機記錄檔之前,將會叫用下列回呼

@Override
public void onBeforeSending(ErrorReport errorReport) {
    // Your code, e.g. to present a custom UI.
}
override fun onBeforeSending(report: ErrorReport?) {
    // Your code, e.g. to present a custom UI.
}

如果端點發生網路問題或中斷,且您重新啟動應用程式, onBeforeSending 則會在進程重新啟動后再次觸發。

SDK 成功傳送當機記錄檔之後,將會叫用下列回呼

@Override
public void onSendingSucceeded(ErrorReport report) {
    // Your code, e.g. to hide the custom UI.
}
override fun onSendingSucceeded(report: ErrorReport?) {
    // Your code, e.g. to hide the custom UI.
}

如果 SDK 無法傳送當機記錄檔,將會叫用下列回呼

@Override
public void onSendingFailed(ErrorReport report, Exception e) {
    // Your code goes here.
}
override fun onSendingFailed(report: ErrorReport?, e: Exception?) {
    // Your code goes here.
}

onSendingFailed接收表示發生無法復原的錯誤,例如 4xx 碼。 例如, 401 表示 appSecret 錯誤。

如果回呼是網路問題,則不會觸發此回呼。 在此情況下,SDK 會持續重試 (,並在網路連線關閉) 時暫停重試。

將附件新增至當機報告

您可以將二進位和文字附件新增至當機報表。 SDK 會連同當機一起傳送它們,讓您可以在 App Center 入口網站中看到它們。 在傳送先前應用程式啟動的預存損毀之前,會立即叫用下列回呼。 噹噹機發生時,不會叫用它。 請確定附件檔案 命名 minidump.dmp 為該名稱保留給迷你傾印檔案。 以下是如何將文字和影像附加至當機的範例:

@Override
public Iterable<ErrorAttachmentLog> getErrorAttachments(ErrorReport report) {

    // Attach some text.
    ErrorAttachmentLog textLog = ErrorAttachmentLog.attachmentWithText("This is a text attachment.", "text.txt");

    // Attach binary data.
    byte[] binaryData = getYourBinary();
    ErrorAttachmentLog binaryLog = ErrorAttachmentLog.attachmentWithBinary(binaryData, "your_filename.jpeg", "image/jpeg");

    // Return attachments as list.
    return Arrays.asList(textLog, binaryLog);
}
override fun getErrorAttachments(report: ErrorReport?): MutableIterable<ErrorAttachmentLog> {

    // Attach some text.
    val textLog = ErrorAttachmentLog.attachmentWithText("This is a text attachment.", "text.txt")

    // Attach binary data.
    val binaryData = getYourBinary()
    val binaryLog = ErrorAttachmentLog.attachmentWithBinary(binaryData, "your_filename.jpeg", "image/jpeg")

    // Return attachments as list.
    return listOf(textLog, binaryLog)
}

注意

大小限制目前為 7 MB。 嘗試傳送較大的附件將觸發錯誤。

在運行時間啟用或停用 App Center 當機

您可以在執行時間啟用和停用 App Center 當機。 如果您停用它,SDK 將不會針對應用程式執行任何損毀報告。

Crashes.setEnabled(false);
Crashes.setEnabled(false)

若要再次啟用App Center當機,請使用相同的API,但傳遞 true 作為參數。

Crashes.setEnabled(true);
Crashes.setEnabled(true)

狀態會保存在裝置的記憶體中,而應用程式會啟動。

此 API 是異步的,您可以在 我們的 App Center 異步 API 指南 中深入瞭解。

注意

只有在啟動之後 Crashes ,才能使用這個方法。

檢查 App Center 當機是否已啟用

您也可以檢查 App Center 當機是否已啟用:

Crashes.isEnabled();
Crashes.isEnabled()

此 API 是異步的,您可以在 App Center 異步 API 指南中深入瞭解。

注意

這個方法只能在啟動之後 Crashes 使用,它一律會在 start 之前傳回 false

已處理的錯誤

App Center 也可讓您使用已處理的例外狀況來追蹤錯誤。 若要這樣做,請使用 trackError 方法:

try {
    // your code goes here.
} catch (Exception exception) {
    Crashes.trackError(exception);
}
try {
    // your code goes here.
} catch (exception: Exception) {
    Crashes.trackError(exception)
}

應用程式可以選擇性地將屬性附加至已處理的錯誤報告,以提供進一步的內容。 將屬性當做索引鍵/值組的對應傳遞, (字串) ,如下列範例所示。

try {
    // your code goes here.
} catch (Exception exception) {
    Map<String, String> properties = new HashMap<String, String>() {{
        put("Category", "Music");
        put("Wifi", "On");
    }};
    Crashes.trackError(exception, properties, null);
}
try {
    // your code goes here.
} catch (exception: Exception) {
    val properties = mapOf("Category" to "Music", "Wifi" to "On")
    Crashes.trackError(exception, properties, null)
}

您也可以選擇性地將二進位和文字附件新增至已處理的錯誤報告。 傳遞附件做為 Iterable ,如下列範例所示。

try {
    // your code goes here.
} catch (Exception exception) {

    // Attach some text.
    ErrorAttachmentLog textLog = ErrorAttachmentLog.attachmentWithText("This is a text attachment.", "text.txt");

    // Attach binary data.
    byte[] binaryData = getYourBinary();
    ErrorAttachmentLog binaryLog = ErrorAttachmentLog.attachmentWithBinary(binaryData, "your_filename.jpeg", "image/jpeg");

    // Track an exception with attachments.
    Crashes.trackError(exception, null, Arrays.asList(textLog, binaryLog));
}
try {
    // your code goes here.
} catch (exception: Exception) {

    // Attach some text.
    val textLog = ErrorAttachmentLog.attachmentWithText("This is a text attachment.", "text.txt")

    // Attach binary data.
    val binaryData = getYourBinary()
    val binaryLog = ErrorAttachmentLog.attachmentWithBinary(binaryData, "your_filename.jpeg", "image/jpeg")

    // Track an exception with attachments.
    Crashes.trackError(exception, null, listOf(textLog, binaryLog))
}

報告 NDK 當機

報告當機

若要在 App Center 中接收適當的當機報告,請先依照上述指示,確定您已設定 App Center 當機 SDK。

建置斷板連結庫

接下來,依照 官方Google Breakpad for Android 自述檔所列的指示,包含並編譯Google Breakpad。

注意

App Center SDK 預設不會組合 Google Breakpad。

附加例外狀況處理程式

一旦您包含Google Breakpad,請在 之後 AppCenter.start附加NDK損毀處理程式:

// Attach NDK Crash Handler after SDK is initialized.
Crashes.getMinidumpDirectory().thenAccept(new AppCenterConsumer<String>() {
    @Override
    public void accept(String path) {

        // Path is null when Crashes is disabled.
        if (path != null) {
            setupNativeCrashesListener(path);
        }
    }
});

方法 setupNativeCrashesListener 是您必須在 C/C++ 中實作的原生方法:

#include "google-breakpad/src/client/linux/handler/exception_handler.h"
#include "google-breakpad/src/client/linux/handler/minidump_descriptor.h"

void Java_com_microsoft_your_package_YourActivity_setupNativeCrashesListener(
        JNIEnv *env, jobject, jstring path) {
    const char *dumpPath = (char *) env->GetStringUTFChars(path, NULL);
    google_breakpad::MinidumpDescriptor descriptor(dumpPath);
    new google_breakpad::ExceptionHandler(descriptor, NULL, dumpCallback, NULL, true, -1);
    env->ReleaseStringUTFChars(path, dumpPath);
}

其中 dumpCallback 用於疑難解答:

/*
 * Triggered automatically after an attempt to write a minidump file to the breakpad folder.
 */
bool dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor,
                  void *context,
                  bool succeeded) {

    // Allow system to log the native stack trace.
    __android_log_print(ANDROID_LOG_INFO, "YourLogTag",
                        "Wrote breakpad minidump at %s succeeded=%d\n", descriptor.path(),
                        succeeded);
    return false;
}

正確設定這些方法之後,應用程式會在重新啟動時自動將迷你傾印傳送至 App Center。 若要進行疑難解答,您可以使用詳細資訊記錄 (AppCenter.setLogLevel(Log.VERBOSE)AppCenter.start ,再) 檢查應用程式重新啟動後是否傳送迷你記錄。

注意

App Center 會使用迷你傾印附件的保留名稱 minidump.dmp 。 除非您是迷你傾印檔案,否則請務必為附件提供不同的名稱,以便我們可以正確處理。

注意

斷板中有已知的 Bug,因此無法在 x86 模擬器上擷取損毀。

符號

如需有關損毀處理的詳細資訊,請參閱 診斷檔