Сбои Центра приложений (Unity)

Важно!

Прекращение поддержки Центра приложений Visual Studio запланировано на 31 марта 2025 г. Хотя вы можете продолжать использовать Центр приложений Visual Studio до полного прекращения его использования, существует несколько рекомендуемых вариантов, на которые можно перейти.

Узнайте больше о сроках поддержки и альтернативных вариантах.

При сбое Центра приложений автоматически создается журнал сбоев при каждом сбое приложения с журналом в хранилище устройства. Когда пользователь снова запускает приложение, пакет SDK отправляет отчет о сбое в Центр приложений. Сбор сбоев работает как для бета-версии, так и для динамических приложений, то есть сбоев, отправленных в Google Play. Журналы сбоев содержат ценные сведения, которые помогут устранить сбой.

Следуйте инструкциям в разделе начало работы Unity, если вы еще не настроили пакет SDK в приложении.

Для журналов сбоев в iOS требуется символика. Чтобы включить символику, обратитесь к документации по диагностике Центра приложений, в которой объясняется, как предоставить символы для приложения.

Важно!

Пакет SDK для аварийного завершения для Unity не поддерживает UWP. Инструкции на этой странице охватывают только Android и iOS.

Примечание

Пакет SDK не будет пересылать журналы сбоев, если вы подключили отладчик. Убедитесь, что отладчик не подключен при сбое приложения.

Примечание

Если вы включили Enable CrashReport API в PlayerSettings, пакет SDK не будет собирать журналы сбоев.

Создание аварийного завершения теста

Сбои Центра приложений предоставляют API для создания тестового сбоя для простого тестирования пакета SDK. Этот API проверяет конфигурации отладки и выпуска. Поэтому его можно использовать только при отладке, так как он не будет работать для приложений выпуска.

Crashes.GenerateTestCrash();

Примечание

Этот метод будет работать только с включенным параметром сборки разработки .

Дополнительные сведения о предыдущем сбое

При сбоях Центра приложений есть два API, которые предоставляют дополнительные сведения на случай сбоя приложения.

Приложение получило предупреждение о нехватке памяти в предыдущем сеансе?

В любое время после запуска пакета SDK можно проверка, если приложение получило предупреждение о памяти в предыдущем сеансе:

bool hadLowMemoryWarning = Crashes.HasReceivedMemoryWarningInLastSessionAsync().Result;

Примечание

Этот метод не будет работать в Awake().

Примечание

В некоторых случаях устройство с нехваткой памяти не может отправлять события.

Произошел сбой приложения в предыдущем сеансе?

В любой момент после запуска пакета SDK можно проверка, если приложение аварийно завершалось при предыдущем запуске:

bool didAppCrash = await Crashes.HasCrashedInLastSessionAsync();

Вызов HasCrashedInLastSessionAsync удобен, если вы хотите настроить поведение или пользовательский интерфейс приложения после сбоя. Некоторые разработчики показывают дополнительный пользовательский интерфейс, чтобы извиниться перед пользователями или хотят связаться с ними после сбоя.

Сведения о последнем сбое

Если приложение ранее завершалось сбоем, вы можете получить сведения о последнем сбое.

ErrorReport crashReport = await Crashes.GetLastSessionCrashReportAsync();

Наиболее распространенным вариантом использования этого API является реализация пользователем своего пользовательского делегата или прослушивателя сбоев.

Настройка использования сбоев Центра приложений

Сбои Центра приложений предоставляют разработчикам обратные вызовы для выполнения дополнительных действий до и при отправке журналов сбоев в Центр приложений.

Примечание

Задайте обратный вызов перед запуском Центра приложений, например в Awake методе , так как центр приложений начинает обработку сбоев сразу после запуска.

Следует ли обработать сбой?

Задайте следующий обратный вызов, если вы хотите решить, нужно ли обрабатывать конкретный сбой. Например, может произойти сбой на уровне системы, который вы хотите игнорировать и не отправлять в Центр приложений.

Crashes.ShouldProcessErrorReport = (ErrorReport report) =>
{
     // Check the report in here and return true or false depending on the ErrorReport.
    return true;
};

Если для вас важна конфиденциальность пользователей, вы можете получить подтверждение пользователя перед отправкой отчета о сбоях в Центр приложений. Пакет SDK предоставляет обратный вызов, который сообщает о сбоях Центра приложений о том, что перед отправкой отчетов о сбоях пользователь ожидает подтверждения.

Если код использует этот обратный вызов, вы несете ответственность за получение подтверждения пользователя. Один из вариантов — диалоговое окно с одним из следующих вариантов: Always Send, Send и Don't send. На основе входных данных вы сообщите Центру приложений, что делать, и сбой будет обрабатываться соответствующим образом.

Примечание

Пакет SDK не отображает диалоговое окно для этого, приложение должно предоставить собственный пользовательский интерфейс для запроса согласия пользователя.

В следующем обратном вызове показано, как сообщить пакету SDK о необходимости дождаться подтверждения пользователя перед отправкой сбоев.

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

Если обратный вызов возвращает true, необходимо получить разрешение пользователя и предоставить пакет SDK с результатом с помощью следующего API:

// Depending on the user's choice, call Crashes.NotifyUserConfirmation() with the right value.
Crashes.NotifyUserConfirmation(UserConfirmation.DontSend);
Crashes.NotifyUserConfirmation(UserConfirmation.Send);
Crashes.NotifyUserConfirmation(UserConfirmation.AlwaysSend);

В качестве примера можно обратиться к нашему примеру настраиваемого диалога.

Получение сведений о состоянии отправки для журнала сбоев

Иногда требуется узнать состояние сбоя приложения. Распространенный вариант использования — отображение пользовательского интерфейса, который информирует пользователя о том, что приложение отправляет отчет о сбоях. Другой сценарий заключается в том, что вы хотите настроить поведение приложения, чтобы обеспечить отправку журналов сбоев вскоре после повторного запуска. Сбои Центра приложений предоставляют три разных обратных вызова, которые можно сделать, чтобы получать уведомления о том, что произошло:

Следующий обратный вызов будет вызван до того, как пакет SDK отправит журнал сбоев

Crashes.SendingErrorReport += (errorReport) =>
{
    // Your code, e.g. to present a custom UI.
};

Если у нас есть проблемы с сетью или сбой в конечной точке, и вы перезапустите приложение, SendingErrorReport активируется снова после перезапуска процесса.

Следующий обратный вызов будет вызван после успешной отправки пакета SDK журнала сбоев.

Crashes.SentErrorReport += (errorReport) =>
{
    // Your code, e.g. to hide the custom UI.
};

Следующий обратный вызов будет вызываться, если пакету SDK не удалось отправить журнал сбоев

Crashes.FailedToSendErrorReport += (errorReport, exception) =>
{
    // Your code goes here.
};

Получение FailedToSendErrorReport означает, что произошла невосстановимая ошибка, например код 4xx . Например, 401 означает, что appSecret неправильно.

Этот обратный вызов не активируется, если это проблема с сетью. В этом случае пакет SDK продолжает повторять попытки (а также приостанавливает повторные попытки, пока сетевое подключение не работает).

Добавление вложений в отчет о сбоях или необработанных исключениях

При необходимости можно добавить двоичные и текстовые вложения в отчет о сбоях или необработанных исключениях . Пакет SDK отправит их вместе с отчетом, чтобы их можно было увидеть на портале Центра приложений. Следующий обратный вызов будет вызван непосредственно перед отправкой сохраненного отчета. Для сбоев это происходит при следующем запуске приложения. Для необработанных исключений необходимо согласиться на отправку вложений. Убедитесь, что файлу вложения не присвоено имя minidump.dmp , так как это имя зарезервировано для файлов minidump. Ниже приведен пример вложения текста и изображения в отчет:

Crashes.GetErrorAttachments = (ErrorReport report) =>
{
    // Your code goes here.
    return new ErrorAttachmentLog[]
    {
        ErrorAttachmentLog.AttachmentWithText("Hello world!", "hello.txt"),
        ErrorAttachmentLog.AttachmentWithBinary(Encoding.UTF8.GetBytes("Fake image"), "fake_image.jpeg", "image/jpeg")
    };
};

Сбои отличаются от необработанных исключений в отчетах со свойством IsCrash . Свойство будет иметь значение true для сбоев, а в противном случае — false.

Примечание

Максимальный размер для вложений в настоящее время составляет 7 МБ. Попытка отправить вложение большего размера вызовет ошибку.

Примечание

GetErrorAttachmentsвызывается в потоке main и не разделяет работу по кадрам. Чтобы избежать блокировки игрового цикла, не выполняйте длительные задачи в этом обратном вызове.

Включение или отключение сбоев Центра приложений во время выполнения

Вы можете включить и отключить сбои Центра приложений во время выполнения. Если вы отключите его, пакет SDK не будет отчеты о сбоях для приложения.

Crashes.SetEnabledAsync(false);

Чтобы снова включить сбои Центра приложений, используйте тот же API, но передайте true в качестве параметра.

Crashes.SetEnabledAsync(true);

Вам не нужно ждать этого вызова, чтобы другие вызовы API (например, IsEnabledAsync) были согласованы.

Состояние сохраняется в хранилище устройства при запусках приложений.

Проверьте, включены ли сбои Центра приложений

Вы также можете проверка, включены ли сбои Центра приложений:

bool isEnabled = await Crashes.IsEnabledAsync();

Обработанное исключение в Unity

Центр приложений также позволяет отслеживать ошибки с помощью обрабатываемых исключений в Unity. Для этого используйте TrackError метод :

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

Для дальнейшего контекста об ошибке можно также прикрепить к ней свойства. Передайте свойства в виде словаря строк. Это необязательный шаг.

try {
    // your code goes here.
} catch (Exception exception) {
    var properties = new Dictionary<string, string>
    {
        { "Category", "Music" },
        { "Wifi", "On" }
    };
    Crashes.TrackError(exception, properties);
}

При необходимости можно добавить двоичные и текстовые вложения в обрабатываемый отчет об ошибках. Передайте вложения в виде массива ErrorAttachmentLog объектов , как показано в примере ниже.

try {
    // your code goes here.
} catch (Exception exception) {
    var attachments = new ErrorAttachmentLog[]
    {
        ErrorAttachmentLog.AttachmentWithText("Hello world!", "hello.txt"),
        ErrorAttachmentLog.AttachmentWithBinary(Encoding.UTF8.GetBytes("Fake image"), "fake_image.jpeg", "image/jpeg")
    };
    Crashes.TrackError(exception, attachments: attachments);
}

Необработанных исключений в Unity

Отчет о необработанных исключениях

По умолчанию пакет SDK центра приложений не сообщает о необработанных исключениях, созданных в приложении, которые не вызывают неустранимый сбой. Чтобы включить эту функцию, вызовите следующий метод:

Crashes.ReportUnhandledExceptions(true);

После вызова этого API Центр приложений регистрирует все необработаенные исключения как проблемы на портале Центра приложений, аналогично обработанным исключениям, упомянутым ранее. Чтобы отключить эту функцию, вызовите тот же API, что и false параметр .

Crashes.ReportUnhandledExceptions(false);

Примечание

Некоторые необработанных исключений, обнаруженные пакетом SDK центра приложений, будут отображаться в пользовательском интерфейсе Центра приложений как ошибки. Это связано с тем, что Unity перехватывает необработанных исключений по умолчанию, то есть приложение не завершает работу и не считается аварийным.

Добавление вложений в отчет об необработанных исключениях

По умолчанию пакет SDK центра приложений не включает вложения в необработанных исключениях. Чтобы включить эту функцию, задайте enableAttachmentsCallback для логического ReportUnhandledExceptions параметра метода значение true:

Crashes.ReportUnhandledExceptions(true, true);

Затем при необходимости можно добавить вложения в отчет об необработанных исключениях, реализовав обратный вызов GetErrorAttachments .

Отчеты о сбоях NDK

Создание отчетов о сбоях

Чтобы получить правильные отчеты о сбоях в Центре приложений, сначала убедитесь, что у вас есть пакет SDK для сбоев Центра приложений, выполнив приведенные выше инструкции.

Создание библиотеки брейк-панели

Затем необходимо включить и скомпилировать Google Breakpad, следуя инструкциям, перечисленным в официальном файле сведений Google Breakpad для Android. Чтобы использовать его в Unity, добавьте двоичный файл в приложение.

Примечание

Пакет SDK центра приложений не содержит Google Breakpad по умолчанию.

Присоединение обработчика исключений

После включения Google Breakpad подключите обработчик сбоя NDK:

/* Attach NDK Crash Handler. */
var minidumpDir = Crashes.GetMinidumpDirectoryAsync();
setupNativeCrashesListener(minidumpDir.Result);

...

[DllImport("YourLib")]
private static extern void setupNativeCrashesListener(string path);

Метод setupNativeCrashesListener является собственным методом, который необходимо реализовать в C/C++:

#include <android/log.h>
#include "google-breakpad/src/client/linux/handler/exception_handler.h"
#include "google-breakpad/src/client/linux/handler/minidump_descriptor.h"

static google_breakpad::ExceptionHandler exception_handler(google_breakpad::MinidumpDescriptor(), NULL, dumpCallback, NULL, true, -1);

/**
 * Registers breakpad as the exception handler for NDK code.
 * @param path minidump directory path returned from Crashes.GetMinidumpDirectoryAsync()
 */
extern "C" void setupNativeCrashesListener(const char *path) {
    google_breakpad::MinidumpDescriptor descriptor(path);
    exception_handler.set_minidump_descriptor(descriptor);
}

Где dumpCallback используется для устранения неполадок:

/*
 * Triggered automatically after an attempt to write a minidump file to the breakpad folder.
 */
static 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;
}

После правильной настройки этих методов приложение автоматически отправляет минидамп в Центр приложений при перезапуске. Для устранения неполадок можно использовать подробные журналы для проверка отправки минидампов после перезапуска приложения.

Примечание

Центр приложений использует зарезервированное имя minidump.dmp для вложений минидампов. Не забудьте присвоить вложению другое имя, если это файл minidump, чтобы мы могли правильно обработать его.

Предупреждение

В брейк-панели есть известная ошибка, из-за которой невозможно записать сбои в эмуляторах x86.

Символика

Дополнительные сведения об обработке сбоев см. в документации по диагностике .