Soluciona errores con Glance

Las funciones de la API para mejorar el manejo de errores en Glance se incluyen a partir de Android 15. En esta página, se proporcionan algunas prácticas recomendadas sobre estas APIs.

Usa un bloque try-catch alrededor de componentes no componibles

Compose no permite bloques try-catch alrededor de elementos componibles, pero te permite unir la otra lógica de tu app en estos bloques. Esto te permite usar Compose para tu vista de error, como se muestra en el siguiente ejemplo:

provideContent {
       var isError = false;
       var data = null
       try {
           val repository = (context.applicationContext as MyApplication).myRepository
           data = repository.loadData()
       } catch (e: Exception) {
           isError = true;
           //handleError
       }

       if (isError) {
           ErrorView()
       } else {
           Content(data)
       }
   }

Diseño de error predeterminado

Si hay una excepción no detectada o un error de Compose, Glance muestra un diseño de error predeterminado:

Un mensaje de error que muestra el tipo de error y una sugerencia para buscarlo
Figura 1: Diseño de error predeterminado de Glance 1.0
Un cuadro con el texto "No se puede mostrar el contenido"
Figura 2: Diseño de error predeterminado de Glance 1.1.0

Glance permite que los desarrolladores proporcionen un diseño XML como resguardo si falla la composición. Esto significa que hubo un error en el código de Compose. Esta IU de error también aparece si tienes un error no detectado en el código de tu app.

class UpgradeWidget : GlanceAppWidget(errorUiLayout = R.layout.error_layout)

Este diseño es estático y el usuario no puede interactuar con él, pero es útil en casos de emergencia.

Contiene un encabezado y un campo de texto para mostrar un mensaje de error.
Figura 3: Ejemplo de diseño de error personalizado

Agrega acciones a la IU de error predeterminada

A partir de Glance 1.1.0, Glance te permite anular el código de manejo de errores predeterminado. De esta manera, puedes agregar devoluciones de llamada de acción en caso de que se produzca una excepción o un error en la composición que no se haya detectado.

Para usar esta función, anula la función onCompositionError():

GlanceAppWidget.onCompositionError(
    context: Context,
    glanceId: GlanceId,
    AppWidgetId: Int,
    throwable: Throwable
)

En esta función, Glance recurre a la API de RemoteViews para el manejo de errores. Esto te permite especificar diseños y controladores de acciones con XML.

En los siguientes ejemplos, se muestra paso a paso cómo crear una IU de error que incluya un botón para enviar comentarios:

  1. Escribe el archivo error_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   style="@style/Widget.MyApplication.AppWidget.Error"
   android:id="@android:id/background"
   android:layout_width="match_parent"
   android:textSize="24sp"
   android:layout_height="match_parent"
   android:orientation="vertical">


   <TextView
       android:id="@+id/error_title_view"
       android:layout_width="match_parent"
       android:textColor="@color/white"
       android:textFontWeight="800"
       android:layout_height="wrap_content"
       android:text="Example Widget Error" />

   <LinearLayout
       android:layout_width="match_parent"
       android:orientation="horizontal"
       android:paddingTop="4dp"
       android:layout_height="match_parent">

       <ImageButton
           android:layout_width="64dp"
           android:layout_height="64dp"
           android:layout_gravity="center"
           android:tint="@color/white"
           android:id="@+id/error_icon"
           android:src="@drawable/heart_broken_fill0_wght400_grad0_opsz24"
       />
       <TextView
           android:id="@+id/error_text_view"
           android:layout_width="wrap_content"
           android:textColor="@color/white"
           android:layout_height="wrap_content"
           android:layout_gravity="center"
           android:padding="8dp"
           android:textSize="16sp"
           android:layout_weight="1"
           android:text="Useful Error Message!" />
   </LinearLayout>

</LinearLayout>

  1. Anula la función onCompositionError
override fun onCompositionError(
   context: Context,
   glanceId: GlanceId,
   AppWidgetId: Int,
   throwable: Throwable
) {
   val rv = RemoteViews(context.packageName, R.layout.error_layout)
   rv.setTextViewText(
       R.id.error_text_view,
       "Error was thrown. \nThis is a custom view \nError Message: `${throwable.message}`"
   )
   rv.setOnClickPendingIntent(R.id.error_icon, getErrorIntent(context, throwable))
   AppWidgetManager.getInstance(context).updateAppWidget(AppWidgetId, rv)
}

  1. Crea un intent pendiente que haga referencia a tu GlanceAppWidgetReceiver
private fun getErrorIntent(context: Context, throwable: Throwable): PendingIntent {
    val intent = Intent(context, UpgradeToHelloWorldPro::class.java)
    intent.setAction("widgetError")
    return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
}

  1. Controla el intent en tu GlanceAppWidgetReceiver
override fun onReceive(context: Context, intent: Intent) {
   super.onReceive(context, intent)
   Log.e("ErrorOnClick", "Button was clicked.");
}