以下部分介绍了如何更新 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 托管在不同的进程中。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 协程。