fix: 先await统计基准再监听事件,消除竞态

根因:fetchStatistics(false)和fetchStatistics(checkDots=true)
是两个独立协程竞争,lastStats更新时机不可控。

修复:onViewCreated中用协程顺序执行:
1. 先 await safeApiCall → 设好 lastStats 基准
2. 再 observeEvents 开始监听通知
EventBus buffer=64 暂存期间的通知不丢失

这样当NewTaskArrived触发fetchStatistics(checkDots=true)时,
lastStats一定已有值,preNotificationStats也能正确保存。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongliang
2026-04-29 19:50:55 +09:30
parent 459049fb16
commit c754edd63b

View File

@@ -122,18 +122,29 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
// 启动时钟定时器
startClockUpdater()
// 主动获取当前电量ACTION_BATTERY_CHANGED 是粘性广播,但 EventBus 可能丢失首次事件)
// 主动获取当前电量
initBatteryStatus()
// 加载任务统计数据
fetchStatistics()
// 加载统计数据(设好 lastStats 基准),再监听事件
// EventBus buffer=64 会暂存期间的通知,不丢失
viewLifecycleOwner.lifecycleScope.launch {
// 同步等待统计数据返回
val result = safeApiCall { taskApi.getStatistics() }
if (result is ApiResult.Success && result.data != null) {
val data = result.data
tvPoolNum.text = data.waitForTask.toString()
tvPunchNum.text = data.treatTask.toString()
tvCompleteNum.text = data.incompleteTask.toString()
notificationManager.lastStats = data
Timber.d("首页: lastStats 基准已设置 ${data}")
}
// 监听 MQTT 事件
// 基准设好后再开始监听事件
observeEvents()
}
// 监听打卡状态
observePunchState()
}
override fun onResume() {
@@ -143,8 +154,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
renderDots()
return
}
// 有未读通知 → 用 preNotificationStats 精确对比
// onResume 时 view 可能重建,需要重新请求 API
// 有未读通知 → 刷新统计 + 红点
fetchStatistics(checkDots = true)
}