多形态设备
多形态设备 · androidx.wear.compose
Glance AppWidget:声明 UI,显式触发更新Wear 1.7.0-alpha07
用 provideGlance、持久状态与 updateAll 管理主屏小组件。
最后更新 2026-08-01
复制即用
class StatusWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
val initial = loadStatus(context)
provideContent {
StatusContent(initial)
}
}
}
class StatusWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget = StatusWidget()
}
suspend fun refreshWidgets(context: Context) {
StatusWidget().updateAll(context)
}声明式 UI,但不是 Compose 组件库
Glance 使用 @Composable 写法,但不是把普通 Compose UI 树直接嵌入桌面:
| 普通 Compose | Glance |
|---|---|
Modifier | GlanceModifier |
Column/Row/Box | Column/Row/Box(Glance 自己的) |
Text/Image | Text/Image(Glance 版本) |
| 自定义绘制 | 有限组件集合 |
| 无限 recomposition | 显式 update 驱动 |
它最终运行在 AppWidget 宿主的能力边界内,因此使用 GlanceModifier 与 Glance 自己的布局、文本和 action API,不能随意复用手机页面里的 Composable。
状态与更新时机
class StatusWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
val status by rememberGlanceObject(key) { loadStatus(context) }
Text(status.value)
}
}
}provideGlance:首次渲染前加载数据。provideContent:观察持久数据源。- 应用其他位置修改数据后:
update(单个)或updateAll(全部)。 - 周期刷新:交给 WorkManager,不要在 composition 内启动永不结束的轮询。
// 触发单个 widget 刷新
suspend fun refreshOne(context: Context, id: GlanceId) {
StatusWidget().update(context, id)
}
// 触发全部刷新(数据全局变化时)
suspend fun refreshAll(context: Context) {
StatusWidget().updateAll(context)
}常见陷阱
- 主线程刷新:
update/updateAll是挂起函数,记得放后台协程。 - 在 composition 里轮询:AppWidget 宿主生命周期不由你控制,轮询会泄漏。
- 复用普通 Composable:Glance 组件集有限,别 import 手机版组件。
- 忘注册 Receiver:
GlanceAppWidgetReceiver必须在 manifest 声明。
要点
GlanceAppWidget.provideGlance声明 UI;GlanceAppWidgetReceiver注册入口。- 先加载数据再
provideContent;数据变化显式update/updateAll。 - 周期刷新用 WorkManager;composition 内不轮询。
- 运行在 AppWidget 宿主边界内,组件集有限。