管理及更新 GlanceAppWidget

以下各節說明如何更新 GlanceAppWidget 及管理其狀態。

管理「GlanceAppWidget」狀態

每當小工具建立或需要更新時,系統都會例項化提供的 GlanceAppWidget 類別,因此該類別應為無狀態且被動

狀態的概念可分為下列幾種:

  • 應用程式狀態:小工具所需的應用程式狀態或內容。例如使用者定義的儲存目的地清單 (即資料庫)。
  • Glance 狀態:僅與應用程式小工具相關的特定狀態,不一定會修改或影響應用程式的狀態。例如,小工具中已選取核取方塊,或計數器已增加。

使用應用程式狀態

應用程式小工具應為被動式。每個應用程式都負責管理資料層,以及處理狀態 (例如閒置、載入和錯誤),這些狀態會反映在小工具 UI 中。

舉例來說,下列程式碼會從存放區層的記憶體內快取擷取目的地、提供儲存的目的地清單,並根據目的地狀態顯示不同的 UI:

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

每當狀態或資料變更時,應用程式有責任通知並更新小工具。詳情請參閱「更新 GlanceAppWidget」。

更新「GlanceAppWidget

你可以使用 GlanceAppWidget 要求更新小工具內容。如「管理 GlanceAppWidget 狀態」一節所述,應用程式小工具是代管在不同的程序中。Glance 會將內容翻譯成實際 RemoteViews,然後傳送給主辦人。如要更新內容,Glance 必須重新建立 RemoteViews 並再次傳送。

如要傳送更新,請呼叫 GlanceAppWidget 例項的 update 方法,並提供 contextglanceId

MyAppWidget().update(context, glanceId)

如要取得 glanceId,請查詢 GlanceAppWidgetManager

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

或者,您也可以使用下列其中一個 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
}

您可以在應用程式的任何部分呼叫這些方法。由於這些是 suspend 函式,建議您在主執行緒範圍外啟動這些函式。在以下範例中,這些函式會在 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()
    }
}

如要進一步瞭解協同程式,請參閱「Android 上的 Kotlin 協同程式」。

更新小工具的時機

立即或定期更新小工具。

應用程式喚醒時,小工具可以立即更新。例如:

  • 使用者與小工具互動,觸發動作、lambda 呼叫或啟動活動的意圖。
  • 使用者與應用程式互動時 (應用程式必須在前台運作),或應用程式已在更新,以回應 Firebase 雲端通訊 (FCM) 訊息或廣播時。

在這些情況下,請按照本指南的說明呼叫 update 方法。

應用程式未喚醒時,小工具可以定期更新。例如:

  • 使用 updatePeriodMillis 更新小工具,每 30 分鐘最多更新一次。
  • 使用 WorkManager 安排更頻繁的更新,例如每 15 分鐘更新一次。
  • 根據廣播更新小工具。

資源