App Center (Android) 損毀

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 使用,它一律會在開始之前傳回 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 模擬器上擷取當機。

符號

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