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 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 incluir 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 = listOf<String>() try { val repository = (context.applicationContext as MyApplication).myRepository data = repository.loadData() } catch (e: Exception) { isError = true // TODO: handle error } 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:
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) { // ... }
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 una excepción o un error no detectado en la composición.
Para usar esta función, anula la
onCompositionError() función:
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 incluye un botón para enviar comentarios:
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>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) }
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.action = "widgetError" return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) }
Controla el intent en tu
GlanceAppWidgetReceiver:override fun onReceive(context: Context, intent: Intent) { super.onReceive(context, intent) Log.e("ErrorOnClick", "Button was clicked.") }