Поделиться через


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

Это важно

Центр приложений Visual Studio был прекращен 31 марта 2025 г., за исключением функций аналитики и диагностики, которые будут поддерживаться до 30 июня 2026 г. Подробнее.

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

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

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

Это важно

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

Замечание

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

Замечание

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

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

App Center Crashes предоставляет API для генерации тестового сбоя, что упрощает тестирование пакета SDK. Этот API проверяет конфигурации отладки и выпуска. Его можно использовать только для отладки, так как оно не будет работать в релизных приложениях.

Crashes.GenerateTestCrash();

Замечание

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

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

App Center Crashes предоставляет два API, которые дают вам больше информации в случае сбоя вашего приложения.

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

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

bool hadLowMemoryWarning = Crashes.HasReceivedMemoryWarningInLastSessionAsync().Result;

Замечание

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

Замечание

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

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

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

bool didAppCrash = await Crashes.HasCrashedInLastSessionAsync();

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

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

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

ErrorReport crashReport = await Crashes.GetLastSessionCrashReportAsync();

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

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

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

Замечание

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

Следует ли обрабатывать аварию?

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

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

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

Если код использует этот обратный вызов, вы несете ответственность за получение подтверждения пользователя. Одним из вариантов является диалоговое окно с одним из следующих вариантов: 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);

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

Получите информацию о статусе отправки для журнала сбоев

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

Функция обратного вызова будет вызвана перед тем, как 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, поскольку это имя зарезервировано для минидампов. Ниже приведен пример подключения текста и изображения к отчету:

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 вызывается в основном потоке и не распределяет работу между кадрами. Чтобы избежать блокировки цикла игры, не выполняйте длительные задачи в этом обратном вызове.

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

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

Crashes.SetEnabledAsync(false);

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

Crashes.SetEnabledAsync(true);

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

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

Проверка включения аварийного сбоя Центра приложений

Кроме того, можно проверить, включена ли функция App Center Crashes.

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 App Center не сообщает о необработанных исключениях, произошедших в вашем приложении, которые не вызывают фатальный сбой. Чтобы включить эту функцию, вызовите следующий метод:

Crashes.ReportUnhandledExceptions(true);

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

Crashes.ReportUnhandledExceptions(false);

Замечание

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

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

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

Crashes.ReportUnhandledExceptions(true, true);

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

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

Отчетность о сбоях

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

Создание библиотеки breakpad

Затем необходимо включить и скомпилировать Google Breakpad, следуя инструкциям, перечисленным в официальном Google Breakpad для Android README. Чтобы использовать его в 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;
}

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

Замечание

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

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

Существует известная ошибка в Breakpad, что делает невозможным захват сбоев на эмуляторах x86.

Символика

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