Bloqueos de App Center (Unity)

Importante

Visual Studio App Center está programado para la retirada el 31 de marzo de 2025. Aunque puede seguir usando Visual Studio App Center hasta que se retire por completo, hay varias alternativas recomendadas a las que puede considerar la posibilidad de migrar.

Obtenga más información sobre las escalas de tiempo de soporte técnico y las alternativas.

App Center Crashes genera automáticamente un registro de bloqueo cada vez que se bloquea la aplicación, con un registro en el almacenamiento del dispositivo. Cuando un usuario vuelve a iniciar la aplicación, el SDK envía el informe de bloqueo a App Center. La recopilación de bloqueos funciona tanto para aplicaciones beta como en vivo, es decir, bloqueos enviados a Google Play. Los registros de bloqueo contienen información valiosa para ayudarle a corregir el bloqueo.

Siga las instrucciones de la sección Introducción unity si aún no ha configurado el SDK en la aplicación.

Los registros de bloqueo en iOS requieren la simbólica. Para habilitar la simbólica, consulte la documentación de Diagnósticos de App Center, que explica cómo proporcionar símbolos para la aplicación.

Importante

El SDK de bloqueos para Unity no admite UWP. Las instrucciones de esta página cubren solo Android e iOS.

Nota

El SDK no reenviará ningún registro de bloqueo si ha asociado el depurador. Asegúrese de que el depurador no está asociado al bloquear la aplicación.

Nota

Si ha Enable CrashReport API habilitado en PlayerSettings, el SDK no recopilará los registros de bloqueo.

Generación de un bloqueo de prueba

App Center Crashes proporciona una API para generar un bloqueo de prueba para facilitar las pruebas del SDK. Esta API comprueba si hay configuraciones de depuración frente a versiones. Por lo tanto, solo puede usarlo al depurar, ya que no funcionará para las aplicaciones de versión.

Crashes.GenerateTestCrash();

Nota

Este método solo funcionará con la configuración de compilación de desarrollo activada.

Obtener más información sobre un bloqueo anterior

App Center Crashes tiene dos API que proporcionan más información en caso de que la aplicación se bloquee.

¿La aplicación recibió una advertencia de memoria baja en la sesión anterior?

En cualquier momento después de iniciar el SDK, puede comprobar si la aplicación recibió una advertencia de memoria en la sesión anterior:

bool hadLowMemoryWarning = Crashes.HasReceivedMemoryWarningInLastSessionAsync().Result;

Nota

Este método no funcionará en Awake().

Nota

En algunos casos, un dispositivo con poca memoria no puede enviar eventos.

¿Se bloqueó la aplicación en la sesión anterior?

En cualquier momento después de iniciar el SDK, puede comprobar si la aplicación se bloqueó en el inicio anterior:

bool didAppCrash = await Crashes.HasCrashedInLastSessionAsync();

Llamar HasCrashedInLastSessionAsync a es útil si desea ajustar el comportamiento o la interfaz de usuario de la aplicación después de que se haya producido un bloqueo. Algunos desarrolladores muestran una interfaz de usuario adicional para disculparse a sus usuarios o quieren ponerse en contacto después de que se haya producido un bloqueo.

Detalles sobre el último bloqueo

Si la aplicación se bloqueó anteriormente, puede obtener detalles sobre el último bloqueo.

ErrorReport crashReport = await Crashes.GetLastSessionCrashReportAsync();

El caso de uso más común para esta API es cuando un usuario implementa su delegado o agente de escucha personalizados bloqueos.

Personalización del uso de bloqueos de App Center

App Center Crashes proporciona devoluciones de llamada para que los desarrolladores realicen acciones adicionales antes y cuando envían registros de bloqueo a App Center.

Nota

Establezca la devolución de llamada antes de que se inicie App Center, por ejemplo, en Awake el método , ya que App Center comienza a procesar se bloquea inmediatamente después del inicio.

¿Se debe procesar el bloqueo?

Establezca la siguiente devolución de llamada si desea decidir si es necesario procesar o no un bloqueo determinado. Por ejemplo, podría haber un bloqueo de nivel de sistema que quiera omitir y no enviar a App Center.

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

Si la privacidad del usuario es importante para ti, es posible que quieras recibir la confirmación del usuario antes de enviar un informe de bloqueo a App Center. El SDK expone una devolución de llamada que indica a App Center Crashes que espere la confirmación del usuario antes de enviar informes de bloqueos.

Si el código usa esta devolución de llamada, es responsable de obtener la confirmación del usuario. Una opción es a través de un mensaje de diálogo con una de las siguientes opciones: Enviar siempre, Enviar y No enviar. En función de la entrada, indicará a App Center qué hacer y, a continuación, se controlará el bloqueo según corresponda.

Nota

El SDK no muestra un cuadro de diálogo para esto, la aplicación debe proporcionar su propia interfaz de usuario para solicitar el consentimiento del usuario.

La siguiente devolución de llamada muestra cómo indicar al SDK que espere la confirmación del usuario antes de enviar bloqueos:

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

Si la devolución de llamada devuelve true, debe obtener el permiso de usuario y enviar un mensaje al SDK con el resultado mediante la SIGUIENTE 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);

Como ejemplo, puede hacer referencia a nuestro ejemplo de diálogo personalizado.

Obtener información sobre el estado de envío de un registro de bloqueo

En ocasiones, quieres conocer el estado del bloqueo de la aplicación. Un caso de uso común es mostrar una interfaz de usuario que informa al usuario de que la aplicación está enviando un informe de bloqueo. Otro escenario es cuando desea ajustar el comportamiento de la aplicación para asegurarse de que los registros de bloqueo se pueden enviar poco después del inicio. Bloqueos de App Center proporciona tres devoluciones de llamada diferentes que puede realizar para recibir una notificación de lo que se ha realizado:

La siguiente devolución de llamada se invocará antes de que el SDK envíe un registro de bloqueos.

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

En caso de que tengamos problemas de red o una interrupción en el punto de conexión y reinicie la aplicación, SendingErrorReport se desencadenará de nuevo después del reinicio del proceso.

La siguiente devolución de llamada se invocará después de que el SDK haya enviado correctamente un registro de bloqueo.

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

Se invocará la siguiente devolución de llamada si el SDK no ha podido enviar un registro de bloqueos.

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

FailedToSendErrorReport Recibir significa que se ha producido un error no recuperable, como un código 4xx. Por ejemplo, 401 significa que el error appSecret es incorrecto.

Esta devolución de llamada no se desencadena si se trata de un problema de red. En este caso, el SDK mantiene el reintento (y también detiene los reintentos mientras la conexión de red está inactiva).

Agregar datos adjuntos a un bloqueo o a un informe de excepciones no controladas

También puede agregar datos adjuntos binarios y de texto a un bloqueo o a un informe de excepciones no controladas . El SDK los enviará junto con el informe para que pueda verlos en el portal de App Center. La siguiente devolución de llamada se invocará justo antes de enviar el informe almacenado. En el caso de los bloqueos, se produce en el siguiente inicio de la aplicación. Para las excepciones no controladas, debe optar por enviar datos adjuntos. Asegúrese de que el archivo adjunto no tiene nombre minidump.dmp , ya que ese nombre está reservado para los archivos minivolcados. Este es un ejemplo de cómo adjuntar texto y una imagen a un informe:

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

Los bloqueos se diferencian de las excepciones no controladas en los informes con la IsCrash propiedad . La propiedad será true para bloqueos y false en caso contrario.

Nota

El límite de tamaño es para datos adjuntos actualmente de 7 MB. Si intenta enviar datos adjuntos más grandes, se producirá un error.

Nota

GetErrorAttachments se invoca en el subproceso principal y no divide el trabajo en fotogramas. Para evitar bloquear el bucle del juego, no realice ninguna tarea de larga duración en esta devolución de llamada.

Habilitación o deshabilitación de bloqueos de App Center en tiempo de ejecución

Puede habilitar y deshabilitar bloqueos de App Center en tiempo de ejecución. Si la deshabilita, el SDK no realizará ningún informe de bloqueos para la aplicación.

Crashes.SetEnabledAsync(false);

Para habilitar los bloqueos de App Center de nuevo, use la misma API, pero pase true como parámetro.

Crashes.SetEnabledAsync(true);

No es necesario esperar esta llamada para que otras llamadas API (como IsEnabledAsync) sean coherentes.

El estado se conserva en el almacenamiento del dispositivo en los inicios de la aplicación.

Comprobación de si los bloqueos de App Center están habilitados

También puede comprobar si los bloqueos de App Center están habilitados:

bool isEnabled = await Crashes.IsEnabledAsync();

Excepciones controladas en Unity

App Center también le permite realizar un seguimiento de los errores mediante excepciones controladas en Unity. Para ello, use el TrackError método :

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

Para obtener más contexto sobre el error, también puede adjuntarle propiedades. Pase las propiedades como un diccionario de cadenas. Este paso es opcional.

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

También puede agregar datos adjuntos binarios y de texto a un informe de errores controlado. Pase los datos adjuntos como una matriz de ErrorAttachmentLog objetos como se muestra en el ejemplo siguiente.

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

Excepciones no controladas en Unity

Notificar excepciones no controladas

De forma predeterminada, el SDK de App Center no notifica excepciones no controladas iniciadas en la aplicación que no provocan un bloqueo grave. Para habilitar esta funcionalidad, llame al método siguiente:

Crashes.ReportUnhandledExceptions(true);

Después de llamar a esta API, App Center registra todas las excepciones no controladas como Problemas en el portal de App Center, de forma similar a las excepciones controladas mencionadas anteriormente. Para deshabilitar esta funcionalidad, llame a la misma API que pasa false el parámetro .

Crashes.ReportUnhandledExceptions(false);

Nota

Algunas excepciones no controladas detectadas por el SDK de App Center aparecerán como errores en la interfaz de usuario de App Center. Esto se debe a que Unity detecta excepciones no controladas de forma predeterminada, lo que significa que la aplicación no sale y no se considera un bloqueo.

Agregar datos adjuntos a un informe de excepción no controlado

De forma predeterminada, el SDK de App Center no habilita los datos adjuntos en excepciones no controladas. Para habilitar esta funcionalidad, establezca el enableAttachmentsCallback parámetro booleano del ReportUnhandledExceptions método en true:

Crashes.ReportUnhandledExceptions(true, true);

A continuación, puede agregar datos adjuntos opcionalmente a un informe de excepciones no controladas mediante la implementación de la devolución de llamada GetErrorAttachments .

Informes de bloqueos de NDK

Informes de bloqueos

Para recibir informes de bloqueo adecuados en App Center, primero asegúrese de que tiene configurado el SDK de bloqueos de App Center siguiendo las instrucciones indicadas anteriormente.

Creación de la biblioteca del panel de interrupción

A continuación, debes incluir y compilar Google Breakpad siguiendo las instrucciones indicadas en el Google Breakpad oficial para Android README. Para usarlo en Unity, incluya el binario con la aplicación.

Nota

El SDK de App Center no agrupa Google Breakpad de forma predeterminada.

Adjuntar el controlador de excepciones

Una vez incluido Google Breakpad, adjunte el controlador de bloqueo NDK:

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

...

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

El método es un método setupNativeCrashesListener nativo que debe implementar en 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);
}

Dónde dumpCallback se usa para solucionar problemas:

/*
 * 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;
}

Una vez configurados correctamente estos métodos, la aplicación envía el minivolcado a App Center automáticamente al reiniciarse. Para solucionar problemas, puede usar registros detallados para comprobar si se envían minivolcados después de reiniciar la aplicación.

Nota

App Center usa el nombre minidump.dmp reservado para los datos adjuntos de minivolcado. Asegúrese de asignar un nombre diferente a los datos adjuntos a menos que sea un archivo de minivolcado para que podamos controlarlo correctamente.

Advertencia

Hay un error conocido en el panel de interrupción que hace imposible capturar bloqueos en emuladores x86.

Símbolos

Consulte la documentación de diagnóstico para obtener más información sobre el procesamiento de bloqueos.