classDestinationAppWidget:GlanceAppWidget(){// ...@ComposablefunMyContent(){valrepository=remember{DestinationsRepository.getInstance()}// Retrieve the cache data everytime the content is refreshedvaldestinationsbyrepository.destinations.collectAsState(State.Loading)when(destinations){isState.Loading->{// show loading content}isState.Error->{// show widget error content}isState.Completed->{// show the list of destinations}}}}
// Updates all placed instances of MyAppWidgetMyAppWidget().updateAll(context)// Iterate over all placed instances of MyAppWidget and update if the state of// the instance matches the given predicateMyAppWidget().updateIf<State>(context){state->
state==State.Completed}
classDataSyncWorker(valcontext:Context,valparams:WorkerParameters,):CoroutineWorker(context,params){overridesuspendfundoWork():Result{// Fetch data or do some work and then update all instance of your widgetMyAppWidget().updateAll(context)returnResult.success()}}
[null,null,["上次更新時間:2025-08-25 (世界標準時間)。"],[],[],null,["# Manage and update GlanceAppWidget\n\nThe following sections describe how to update `GlanceAppWidget` and manage its\nstate.\n\nManage `GlanceAppWidget` state\n------------------------------\n\nThe provided `GlanceAppWidget` class is instantiated whenever the widget is\ncreated or requires an update, so it should be *stateless and passive*.\n| **Key Point:** App widgets live in a different process. While the defined UI content (meaning the underlying `RemoteViews`) is restored by the system, any state kept in-memory, for example in the app's scope, can be destroyed at any time.\n\nThe concept of state can be divided into the following:\n\n- **Application state**: The state or content of the app that is required by the widget. For example, a list of stored destinations (i.e., database) defined by the user.\n- **Glance state**: The specific state that is only relevant to the app widget and does not necessarily modify or affect the app's state. For example, a checkbox was selected in the widget or a counter was increased.\n\n### Use application state\n\nApp widgets should be passive. Each application is responsible for managing the\ndata layer and handling the states, such as idle, loading, and error reflecting\nin the widget UI.\n\nFor example, the following code retrieves the destinations from the in-memory\ncache from the repository layer, provides the stored list of destinations, and\ndisplays a different UI depending on its state:\n\n\n```kotlin\nclass DestinationAppWidget : GlanceAppWidget() {\n\n // ...\n\n @Composable\n fun MyContent() {\n val repository = remember { DestinationsRepository.getInstance() }\n // Retrieve the cache data everytime the content is refreshed\n val destinations by repository.destinations.collectAsState(State.Loading)\n\n when (destinations) {\n is State.Loading -\u003e {\n // show loading content\n }\n\n is State.Error -\u003e {\n // show widget error content\n }\n\n is State.Completed -\u003e {\n // show the list of destinations\n }\n }\n }\n}https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceSnippets.kt#L368-L392\n```\n\n\u003cbr /\u003e\n\nWhenever the state or the data changes, it is the app's responsibility to notify\nand update the widget. See [Update GlanceAppWidget](/develop/ui/compose/glance/glance-app-widget#update-glance-appwidget) for more information.\n| **Note:** See the [Optimizations for updating widget content](/guide/topics/appwidgets/advanced#update-widgets) section in the app widgets guide to understand how and when to update.\n\nUpdate `GlanceAppWidget`\n------------------------\n\nYou can request to update your widget content using `GlanceAppWidget`. As\nexplained in the [Manage `GlanceAppWidget` state](#manage-state) section, app\nwidgets are hosted in a different process. Glance translates the content into\nactual `RemoteViews` and sends them to the host. To update the content, Glance\nmust recreate the `RemoteViews` and send them again.\n\nTo send the update, call the `update` method of the `GlanceAppWidget` instance,\nproviding the `context` and the `glanceId`:\n\n\n```kotlin\nMyAppWidget().update(context, glanceId)https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceSnippets.kt#L397-L397\n```\n\n\u003cbr /\u003e\n\nTo obtain the `glanceId`, query the `GlanceAppWidgetManager`:\n\n\n```kotlin\nval manager = GlanceAppWidgetManager(context)\nval widget = GlanceSizeModeWidget()\nval glanceIds = manager.getGlanceIds(widget.javaClass)\nglanceIds.forEach { glanceId -\u003e\n widget.update(context, glanceId)\n}https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceSnippets.kt#L401-L406\n```\n\n\u003cbr /\u003e\n\nAlternatively, use one of the `GlanceAppWidget update` extensions:\n\n\n```kotlin\n// Updates all placed instances of MyAppWidget\nMyAppWidget().updateAll(context)\n\n// Iterate over all placed instances of MyAppWidget and update if the state of\n// the instance matches the given predicate\nMyAppWidget().updateIf\u003cState\u003e(context) { state -\u003e\n state == State.Completed\n}https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceSnippets.kt#L410-L417\n```\n\n\u003cbr /\u003e\n\nThese methods can be called from any part of your application. Because they are\n`suspend` functions, we recommend launching them outside of the main thread\nscope. In the following example, they are launched in a `CoroutineWorker`:\n\n\n```kotlin\nclass DataSyncWorker(\n val context: Context,\n val params: WorkerParameters,\n) : CoroutineWorker(context, params) {\n\n override suspend fun doWork(): Result {\n // Fetch data or do some work and then update all instance of your widget\n MyAppWidget().updateAll(context)\n return Result.success()\n }\n}https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceSnippets.kt#L422-L432\n```\n\n\u003cbr /\u003e\n\nSee [Kotlin Coroutines on Android](/kotlin/coroutines) for more details on coroutines.\n\n### When to update widgets\n\nUpdate widgets either immediately or periodically.\n\nYour widget can update immediately when your app is awake. For example:\n\n- When a user interacts with a widget, triggering an action, a lambda call, or an intent to launch an activity.\n- When your user interacts with your app in the foreground, or while the app is already updating in response to a Firebase Cloud Messaging (FCM) message or a broadcast.\n\nIn these cases, call the [`update`](/reference/kotlin/androidx/glance/appwidget/GlanceAppWidget#update(android.content.Context,androidx.glance.GlanceId)) method as described in this guide.\n\nYour widget can update periodically when your app isn't awake. For example:\n\n- Use [`updatePeriodMillis`](/reference/android/appwidget/AppWidgetProviderInfo#updatePeriodMillis) to update the widget up to once every 30 minutes.\n- Use `WorkManager` to schedule more frequent updates, such as every 15 minutes.\n- Update the widget in response to a broadcast.\n\n| **Important:** Avoid updating your widget every minute when the app isn't awake, as frequent updates drain your users' battery.\n\nResources\n---------\n\n- [Create a widget with Glance](/codelabs/glance) (Codelab)\n- [Building for the Future of Android: Widgets chapter](https://www.youtube.com/watch?v=YKPqjsYBFvI&t=487s) (Video)"]]