Gestisci e aggiorna GlanceAppWidget

Le seguenti sezioni descrivono come aggiornare GlanceAppWidget e gestirne lo stato.

Gestisci stato GlanceAppWidget

Viene creata un'istanza della classe GlanceAppWidget fornita ogni volta che il widget viene creato o richiede un aggiornamento, pertanto dovrebbe essere stateless e passiva.

Il concetto di stato può essere suddiviso come segue:

  • Stato applicazione: lo stato o i contenuti dell'app richiesti dal widget. Ad esempio, un elenco di destinazioni archiviate (ovvero database) definite dall'utente.
  • Stato Glance: lo stato specifico che è pertinente soltanto per il widget dell'app e non modifica né influisce necessariamente sullo stato dell'app. Ad esempio, nel widget è stata selezionata una casella di controllo o è stato aumentato un contatore.

Usa stato applicazione

I widget delle app devono essere passivi. Ogni applicazione è responsabile della gestione del livello dati e degli stati, come inattività, caricamento e visualizzazione degli errori nella UI del widget.

Ad esempio, il seguente codice recupera le destinazioni dalla cache in memoria dal livello del repository, fornisce l'elenco delle destinazioni archiviate e mostra una UI diversa a seconda dello stato:

class DestinationAppWidget : GlanceAppWidget() {

    // ...

    @Composable
    fun MyContent() {
        val repository = remember { DestinationsRepository.getInstance() }
        // Retrieve the cache data everytime the content is refreshed
        val destinations by repository.destinations.collectAsState(State.Loading)

        when (destinations) {
            is State.Loading -> {
                // show loading content
            }

            is State.Error -> {
                // show widget error content
            }

            is State.Completed -> {
                // show the list of destinations
            }
        }
    }
}

Ogni volta che lo stato o i dati cambiano, è responsabilità dell'app avvisare e aggiornare il widget. Vedi Aggiornamento di GlanceAppWidget per ulteriori informazioni.

Aggiorna GlanceAppWidget

Come spiegato nella sezione Gestisci lo stato di GlanceAppWidget, i widget delle app sono ospitati con un processo diverso. Glance traduce i contenuti in RemoteViews effettivi e li invia all'host. Per aggiornare i contenuti, Glance deve ricreare il file RemoteViews e inviarlo di nuovo.

Per inviare l'aggiornamento, chiama il metodo update dell'istanza GlanceAppWidget, fornendo context e glanceId:

MyAppWidget().update(context, glanceId)

Per ottenere glanceId, esegui una query su GlanceAppWidgetManager:

val manager = GlanceAppWidgetManager(context)
val widget = GlanceSizeModeWidget()
val glanceIds = manager.getGlanceIds(widget.javaClass)
glanceIds.forEach { glanceId ->
    widget.update(context, glanceId)
}

In alternativa, utilizza una delle estensioni GlanceAppWidget update:

// Updates all placed instances of MyAppWidget
MyAppWidget().updateAll(context)

// Iterate over all placed instances of MyAppWidget and update if the state of
// the instance matches the given predicate
MyAppWidget().updateIf<State>(context) { state ->
    state == State.Completed
}

Questi metodi possono essere chiamati da qualsiasi parte dell'applicazione. Poiché sono funzioni suspend, ti consigliamo di avviarle al di fuori dell'ambito dei thread principale. Nell'esempio seguente, vengono lanciati in un CoroutineWorker:

class DataSyncWorker(
    val context: Context,
    val params: WorkerParameters,
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        // Fetch data or do some work and then update all instance of your widget
        MyAppWidget().updateAll(context)
        return Result.success()
    }
}

Per ulteriori dettagli sulle coroutine, vedi Kotlin Coroutines su Android.