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

Android Wear组件数据更新频繁问题:DataStorage异常排查

问题分析与解决方案

你的代码存在几个关键问题,导致Complication数据更新过于频繁:

1. 定时延迟时间与需求不符

DataStorage的startScheduledUpdates()方法中,delay(30000)设置的是30秒间隔,但你需要的是10秒刷新,这里数值和注释不匹配,是明显的时间配置错误。

2. 重复启动定时任务

每次ShortTextDataSourceService被系统启动时(比如调用requestUpdateAll()触发更新请求),都会执行dataStorage.startScheduledUpdates(),这会创建新的协程循环。多个循环同时运行会导致DataStore被频繁更新,进而触发Complication不断刷新,形成恶性循环。

3. 冗余的DataStore读取操作

在onComplicationRequest()中,你通过dataStorage.observeComplicationState().first()重复读取DataStore数据——其实collect回调已经拿到了最新的状态值,重复读取不仅冗余,还可能因Flow订阅逻辑引发意外的数据流触发。


修正后的代码示例

1. 改造DataStorage为单例,确保定时任务仅启动一次

private val COMPLICATION_STATE_KEY = longPreferencesKey("complication_state")

class DataStorage private constructor(private val context: Context) {

    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    private var isScheduled = false // 标记定时任务是否已启动

    fun startScheduledUpdates() {
        if (isScheduled) return // 避免重复启动
        isScheduled = true

        Log.d("DataStorage", "Scheduled Updates started (10s interval)")
        scope.launch {
            while (true) {
                updateComplicationState()
                delay(10000) // 修正为10秒间隔
            }
        }
    }

    suspend fun updateComplicationState() {
        context.dataStore.edit { preferences ->
            val currentValue = preferences[COMPLICATION_STATE_KEY] ?: 0L
            preferences[COMPLICATION_STATE_KEY] = currentValue + 1
        }
    }

    fun observeComplicationState(): Flow<Long> {
        return context.dataStore.data.map { preferences ->
            preferences[COMPLICATION_STATE_KEY] ?: 0L
        }
    }

    companion object {
        @Volatile
        private var INSTANCE: DataStorage? = null

        fun getInstance(context: Context): DataStorage {
            return INSTANCE ?: synchronized(this) {
                val instance = DataStorage(context.applicationContext)
                INSTANCE = instance
                instance
            }
        }
    }
}

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(
    name = "Complications",
)

2. 优化ShortTextDataSourceService逻辑

private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
private val dataStorage = DataStorage.getInstance(this)
private var latestComplicationState: Long = 0 // 缓存最新状态值

override fun onCreate() {
    super.onCreate()
    observeComplicationData()
    dataStorage.startScheduledUpdates() // 现在只会启动一次定时任务
}

private fun observeComplicationData() {
    scope.launch {
        dataStorage.observeComplicationState().collect { newState ->
            latestComplicationState = newState
            Log.d("ShortTextDataSourceService", "Data updated: $newState")

            // 数据变化时请求Complication更新
            val componentName = ComponentName(this@ShortTextDataSourceService, ShortTextDataSourceService::class.java)
            val requester = ComplicationDataSourceUpdateRequester.create(this@ShortTextDataSourceService, componentName)
            requester.requestUpdateAll()

            Log.d("ShortTextDataSourceService", "Complication update requested")
        }
    }
}

override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
    Log.d("ShortTextDataSourceService", "OLD VALUE :::> $updateCount")
    updateCount = latestComplicationState.toString() // 直接使用缓存值,无需重复读取
    Log.d("ShortTextDataSourceService", "NEW VALUE :::> $updateCount")

    // 返回构建好的Complication数据(示例为短文本类型)
    return ComplicationData.Builder(ComplicationType.SHORT_TEXT)
        .setText(PlainComplicationText.Builder(updateCount).build())
        .build()
}

override fun onDestroy() {
    super.onDestroy()
    scope.cancel() // 销毁时取消协程,避免内存泄漏
}

额外建议

  • 优先使用WorkManager的PeriodicWorkRequest实现定时任务,它能更好地适配Wear OS的后台限制,避免被系统回收或重复启动。
  • 确保在Manifest中正确配置ComplicationDataSourceService的权限和服务属性,避免因系统限制导致的异常行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 02:32:10