You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jetpack Glance组件在小组件中展示Room本地数据库中的笔记数据?

如何使用Jetpack Glance组件在小组件中展示Room本地数据库中的笔记数据?

咱们得先搞清楚:Glance组件和普通App里的Compose不一样,它没法直接用咱们平时依赖注入的ViewModel(毕竟小组件跑在系统进程里,依赖逻辑不通),所以得换个思路——用Glance自带的状态存储来保存笔记数据,再在数据库变化时主动触发小组件刷新。

接下来一步步改你的代码:

1. 让小组件能拿到Room数据(修改AppWidgetReceiver)

你的AppWidgetReceiver已经加了@AndroidEntryPoint,刚好可以直接注入你的EntityRepoImp。咱们在系统触发小组件更新时,从Room拉最新数据,存到Glance的偏好状态里:

@AndroidEntryPoint
class AppWidgetReceiver : GlanceAppWidgetReceiver() {
    @Inject
    lateinit var repo: EntityRepoImp

    override val glanceAppWidget: GlanceAppWidget = AppWidget()

    override fun onUpdate(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetIds: IntArray
    ) {
        super.onUpdate(context, appWidgetManager, appWidgetIds)
        // 开协程在IO线程拿数据,避免阻塞主线程
        CoroutineScope(Dispatchers.IO).launch {
            repo.getAllNotesById.collect { notes ->
                // 给每个已添加的小组件更新状态
                appWidgetIds.forEach { widgetId ->
                    glanceAppWidget.update(context, GlanceId(widgetId)) { preferences ->
                        // 把笔记列表转成JSON字符串存起来(需要Gson序列化)
                        val notesJson = Gson().toJson(notes)
                        preferences.edit {
                            it.putString("saved_notes", notesJson)
                        }
                    }
                }
            }
        }
    }
}

2. 在小组件UI里读取并展示数据(修改AppWidget类)

现在数据已经存在Glance的偏好里了,咱们在Content里把它读出来,解析成笔记列表,再渲染成UI:

class AppWidget : GlanceAppWidget() {
    // 指定用Glance的偏好存储来保存状态
    override val stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition

    @Composable
    override fun Content() {
        // 拿到存储的JSON字符串
        val notesJson = currentState<String?>("saved_notes")
        // 解析成笔记列表,为空的话默认显示空列表
        val notes = notesJson?.let {
            Gson().fromJson(it, object : TypeToken<List<Entity>>() {}.type)
        } ?: emptyList()

        // 用LazyColumn展示所有笔记,适配小组件的滚动需求
        LazyColumn(
            modifier = GlanceModifier.fillMaxSize().padding(horizontal = 16.dp, vertical = 8.dp)
        ) {
            items(notes) { note ->
                // 替换成你的Entity实际字段,比如标题、内容摘要
                Text(
                    text = note.title,
                    modifier = GlanceModifier.padding(bottom = 8.dp),
                    style = TextStyle(fontSize = 16.sp)
                )
            }
        }
    }
}

3. 数据库变化时自动刷新小组件

现在小组件只能在系统触发更新时拿数据,咱们得让它在用户增删改笔记时自动刷新。可以在你的AppWidgetVM里,当Flow收到新数据时发送广播:

先给ViewModel加上Application依赖(用来获取Context):

@HiltViewModel
class AppWidgetVM @Inject constructor(
    private val repo: EntityRepoImp,
    private val application: Application // 新增这个参数
): ViewModel() {
    private val _allNotesById = MutableStateFlow<List<Entity>>(emptyList())
    val allNotesById: StateFlow<List<Entity>>
        get() = _allNotesById.stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(),
            initialValue = listOf()
        )

    init {
        viewModelScope.launch(Dispatchers.IO) {
            repo.getAllNotesById.collect { notes ->
                _allNotesById.value = notes
                // 发送广播通知所有小组件刷新
                val updateIntent = Intent(application, AppWidgetReceiver::class.java).apply {
                    action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
                    // 获取所有已添加的小组件ID
                    val widgetIds = AppWidgetManager.getInstance(application).getAppWidgetIds(
                        ComponentName(application, AppWidgetReceiver::class.java)
                    )
                    putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds)
                }
                application.sendBroadcast(updateIntent)
            }
        }
    }
}

小提醒

  • 别忘了加Gson依赖:在你的build.gradle里添加implementation 'com.google.code.gson:gson:2.10.1',不然没法序列化数据
  • 如果笔记数量很多,别在小组件里展示全部内容,挑关键信息(比如标题)就行,避免UI卡顿或者超出小组件尺寸限制

这样改完之后,你的Glance小组件就能实时同步Room里的本地笔记数据啦!

备注:内容来源于stack exchange,提问作者Youn Tivoli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 11:24:29