以下部分介绍了如何更新 GlanceAppWidget
并管理其状态。
管理 GlanceAppWidget
状态
每当创建 widget 或需要更新 widget 时,系统都会实例化所提供的 GlanceAppWidget
类,因此该类应为无状态且被动。
状态的概念可分为以下几类:
- 应用状态:widget 所需的应用状态或内容。例如,用户定义的已存储目的地列表(即数据库)。
- 概览状态:仅与应用 widget 相关且不一定会修改或影响应用状态的特定状态。例如,在 widget 中选中了一个复选框或增加了计数器。
使用应用状态
应用 widget 应该是被动的。每个应用都负责管理数据层并处理状态(例如反映在 widget 界面中的空闲、加载和错误状态)。
例如,以下代码从代码库层的内存缓存中检索目的地,提供存储的目的地列表,并根据其状态显示不同的界面:
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 } } } }
每当状态或数据发生变化时,应用都有责任通知并更新 widget。如需了解详情,请参阅更新 GlanceAppWidget。
更新GlanceAppWidget
您可以使用 GlanceAppWidget
请求更新 widget 内容。如管理 GlanceAppWidget
状态部分中所述,应用 widget 托管在不同的进程中。Glance 将内容转换为实际的 RemoteViews
并将其发送到宿主。如需更新内容,Glance 必须重新创建 RemoteViews
并再次发送。
如需发送更新,请调用 GlanceAppWidget
实例的 update
方法,并提供 context
和 glanceId
:
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 协程。
何时更新 widget
立即或定期更新 widget。
当应用处于唤醒状态时,widget 可以立即更新。例如:
- 当用户与 widget 互动时,会触发操作、lambda 调用或启动 activity 的 intent。
- 当用户在前台与应用互动时,或者当应用已在响应 Firebase Cloud Messaging (FCM) 消息或广播时更新。
在这些情况下,请按照本指南中的说明调用 update
方法。
即使应用未唤醒,widget 也可以定期更新。例如:
- 使用
updatePeriodMillis
最多每 30 分钟更新一次 widget。 - 使用
WorkManager
可安排更频繁的更新,例如每 15 分钟更新一次。 - 更新 widget 以响应广播。
资源
- 使用 Glance 创建 widget(Codelab)
- 面向未来开发 Android 应用:微件章节(视频)