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

Jetpack Compose Glance读取DataStore偏好始终为默认值怎么办

问题根因
  • 你混淆了Glance内置状态和App自身的Jetpack DataStore:currentState<Preferences>()读取的是Glance框架为小组件单独维护的内部状态存储,和你主界面写入业务配置用的DataStore是完全独立的两个存储实例,两边数据不互通,主界面写入的值根本不会同步到Glance的内部状态里。
  • 取值逻辑被remember包裹:remember块内的代码仅在组件首次进入组合时执行一次,就算后续关联的状态发生变化,也不会重新执行取值逻辑,会一直缓存首次拿到的默认值。
  • 缺少主动刷新触发:主界面写入配置后没有通知Glance框架刷新小组件,小组件处于宿主缓存状态时不会主动拉取最新数据。
修复步骤
  1. 统一数据源,不要用Glance内置Preferences存业务配置
    重写Glance小组件的provideGlance方法,直接收集App全局共用的DataStore数据流,保证和主界面用的是同一个DataStore实例(统一用ApplicationContext初始化单例DataStore,避免多实例数据不互通),示例代码:
    override suspend fun provideGlance(context: Context, id: GlanceId) {
        // 拿到和主界面完全一致的DataStore实例
        val appDataStore = context.applicationContext.pref.data
        provideContent {
            // 持续收集DataStore的更新,数据变化时自动触发重组
            val prefs by appDataStore.collectAsState(
                initial = preferencesOf(stringPreferencesKey("weather_city") to "Paris")
            )
            val city = prefs[stringPreferencesKey("weather_city")] ?: "Paris"
            // 渲染小组件UI,直接使用获取到的city值即可
            WeatherWidgetUi(city)
        }
    }
    
  2. 删除取值逻辑外层的remember包裹
    由collectAsState驱动状态更新,新值会自动触发重组,不需要额外缓存初始值,避免旧值被长期缓存不更新。
  3. 写入配置后主动触发小组件刷新
    在DataStore写入完成后,调用Glance的更新方法主动通知所有小组件实例拉取最新数据,修改原有写入方法:
    suspend fun setWeatherCity(city: String){
        application.applicationContext.pref.edit { preference ->
            preference[stringPreferencesKey("weather_city")] = city
        }
        // 写入完成后刷新所有该类型的小组件
        WeatherWidget().updateAll(application.applicationContext)
    }
    

内容的提问来源于stack exchange,提问作者lerey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:18:13