fix: 红点不显示——SharedFlow(replay=0)事件竞争
根因:EventBus用MutableSharedFlow(replay=0,buffer=0), MainActivity和HomeFragment同时collect,NewTaskArrived 中间事件在emit时挂起(无缓冲),HomeFragment收不到。 修复:去掉NewTaskArrived中间事件,HomeFragment直接在 MqttMessageReceived type=1中处理: 1. 调 notificationManager.onNewTaskMessage() 2. 直接调 activity.showNotificationBanner() 显示横幅 3. fetchStatistics(checkDots=true) 刷新红点 架构简化: - MainActivity不再监听MQTT type=1(去掉observeMqttMessages) - NotificationManager不再emit事件(去掉EventBus依赖) - 去抖合并后通过回调onPendingCountChanged通知UI Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,16 +7,9 @@ import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.xiaoqu.watch.databinding.ActivityMainBinding
|
||||
import com.xiaoqu.watch.event.AppEvent
|
||||
import com.xiaoqu.watch.event.EventBus
|
||||
import com.xiaoqu.watch.service.manager.NotificationManager
|
||||
import com.xiaoqu.watch.service.manager.SystemStateMonitor
|
||||
import com.xiaoqu.watch.ui.widget.NotificationBannerView
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
@@ -32,17 +25,9 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
/** 系统状态监听器(电量、蓝牙状态) */
|
||||
@Inject lateinit var systemStateMonitor: SystemStateMonitor
|
||||
/** 消息通知管理器 */
|
||||
@Inject lateinit var notificationManager: NotificationManager
|
||||
/** 事件总线 */
|
||||
@Inject lateinit var eventBus: EventBus
|
||||
|
||||
/** 通知横幅(HomeFragment 需访问设置点击回调) */
|
||||
/** 通知横幅(HomeFragment 需访问) */
|
||||
lateinit var notificationBanner: NotificationBannerView
|
||||
|
||||
/** Activity 协程作用域 */
|
||||
private val activityScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@@ -68,9 +53,6 @@ class MainActivity : AppCompatActivity() {
|
||||
// 初始化通知横幅
|
||||
notificationBanner = binding.notificationBanner
|
||||
|
||||
// 监听 MQTT 新任务消息,显示横幅
|
||||
observeMqttMessages()
|
||||
|
||||
Timber.d("MainActivity created")
|
||||
}
|
||||
|
||||
@@ -80,26 +62,11 @@ class MainActivity : AppCompatActivity() {
|
||||
notificationBanner.destroy()
|
||||
}
|
||||
|
||||
// ===== MQTT 新任务 → 通知横幅 =====
|
||||
// ===== 通知横幅(由 HomeFragment 调用显示) =====
|
||||
|
||||
/** 监听 MQTT 消息和通知事件 */
|
||||
private fun observeMqttMessages() {
|
||||
activityScope.launch {
|
||||
eventBus.events.collect { event ->
|
||||
when (event) {
|
||||
is AppEvent.MqttMessageReceived -> {
|
||||
if (event.type == 1) {
|
||||
// 交给 NotificationManager 处理(去抖+合并+震动+亮屏)
|
||||
notificationManager.onNewTaskMessage(event.rawJson)
|
||||
}
|
||||
}
|
||||
// NotificationManager 处理完后发出事件 → 显示/更新横幅
|
||||
is AppEvent.NewTaskArrived -> {
|
||||
notificationBanner.show(event.count)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
/** 显示通知横幅(供 HomeFragment 调用) */
|
||||
fun showNotificationBanner(count: Int) {
|
||||
notificationBanner.show(count)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ import com.xiaoqu.watch.data.task.TaskStatistics
|
||||
import com.xiaoqu.watch.device.screen.ScreenController
|
||||
import com.xiaoqu.watch.device.sensor.VibrationController
|
||||
import com.xiaoqu.watch.device.sensor.VibrationDefaults
|
||||
import com.xiaoqu.watch.event.AppEvent
|
||||
import com.xiaoqu.watch.event.EventBus
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@@ -27,8 +25,7 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
class NotificationManager @Inject constructor(
|
||||
private val vibrationController: VibrationController,
|
||||
private val screenController: ScreenController,
|
||||
private val eventBus: EventBus
|
||||
private val screenController: ScreenController
|
||||
) {
|
||||
companion object {
|
||||
/** 去抖间隔(毫秒) */
|
||||
@@ -73,6 +70,9 @@ class NotificationManager @Inject constructor(
|
||||
/** 协程作用域 */
|
||||
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
|
||||
|
||||
/** 去抖合并后的回调(通知 UI 更新横幅数字) */
|
||||
var onPendingCountChanged: ((Int) -> Unit)? = null
|
||||
|
||||
/**
|
||||
* 处理 MQTT type=1 新任务消息
|
||||
* 去抖策略:1s 窗口内的消息暂存,窗口结束后合并处理(不丢弃)
|
||||
@@ -104,8 +104,8 @@ class NotificationManager @Inject constructor(
|
||||
for (json in jsons) {
|
||||
processMessageSilent(json) // 只加 ID,不重复震动
|
||||
}
|
||||
// 合并后统一发一次事件
|
||||
notifyUi()
|
||||
// 合并后通知 UI 更新数字
|
||||
onPendingCountChanged?.invoke(pendingCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,8 +128,7 @@ class NotificationManager @Inject constructor(
|
||||
vibrationController.executePattern(pattern)
|
||||
}
|
||||
screenController.turnOn()
|
||||
|
||||
notifyUi()
|
||||
// UI 更新(横幅+红点)由调用方处理,不再通过 EventBus
|
||||
}
|
||||
|
||||
/** 静默处理(只加 ID,不震动不亮屏,用于合并暂存消息) */
|
||||
@@ -149,12 +148,7 @@ class NotificationManager @Inject constructor(
|
||||
Timber.d("通知: 当前未读 ${_pendingTaskIds.size}")
|
||||
}
|
||||
|
||||
/** 通知 UI 更新(横幅+红点) */
|
||||
private fun notifyUi() {
|
||||
scope.launch {
|
||||
eventBus.emit(AppEvent.NewTaskArrived(_pendingTaskIds.toList(), _pendingTaskIds.size))
|
||||
}
|
||||
}
|
||||
// notifyUi 已移除,UI 更新改由调用方(HomeFragment)直接处理
|
||||
|
||||
/** 消费所有未读消息(用户点击提示条/横幅查看全部) */
|
||||
fun consumeAll() {
|
||||
|
||||
@@ -130,6 +130,12 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
|
||||
// 监听打卡状态
|
||||
observePunchState()
|
||||
|
||||
// 去抖合并后更新横幅数字
|
||||
notificationManager.onPendingCountChanged = { count ->
|
||||
(activity as? com.xiaoqu.watch.app.MainActivity)?.showNotificationBanner(count)
|
||||
fetchStatistics(checkDots = true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@@ -175,12 +181,13 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
// 清理 Activity 回调,避免泄漏
|
||||
// 清理回调,避免泄漏
|
||||
(activity as? com.xiaoqu.watch.app.MainActivity)?.let {
|
||||
it.onSwipeDown = null
|
||||
it.onBackKeyPressed = null
|
||||
it.notificationBanner.onClick = null
|
||||
}
|
||||
notificationManager.onPendingCountChanged = null
|
||||
}
|
||||
|
||||
// ===== 打卡面板 =====
|
||||
@@ -484,12 +491,6 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
is AppEvent.BluetoothStateChanged -> {
|
||||
statusBar.updateBluetooth(event.isOn)
|
||||
}
|
||||
// 新任务到达 → 刷新统计 + 累积红点
|
||||
is AppEvent.NewTaskArrived -> {
|
||||
Timber.d("首页: 新任务到达 (${event.count} 条)")
|
||||
fetchStatistics(checkDots = true)
|
||||
setupBannerClick()
|
||||
}
|
||||
// MQTT 消息
|
||||
is AppEvent.MqttMessageReceived -> {
|
||||
when (event.type) {
|
||||
@@ -498,6 +499,20 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
||||
Timber.d("首页: 收到日常动态")
|
||||
fetchStatistics()
|
||||
}
|
||||
1 -> {
|
||||
// 新任务 → 直接处理(不走中间事件,避免 SharedFlow 竞争)
|
||||
Timber.d("首页: 收到新任务通知")
|
||||
notificationManager.onNewTaskMessage(event.rawJson)
|
||||
// 显示横幅
|
||||
val count = notificationManager.pendingCount
|
||||
if (count > 0) {
|
||||
(activity as? com.xiaoqu.watch.app.MainActivity)
|
||||
?.showNotificationBanner(count)
|
||||
}
|
||||
// 刷新统计 + 红点
|
||||
fetchStatistics(checkDots = true)
|
||||
setupBannerClick()
|
||||
}
|
||||
3 -> {
|
||||
// 解绑 → 停止蓝牙 → 清除数据 → 跳绑定页
|
||||
Timber.d("首页: 收到解绑消息")
|
||||
|
||||
Reference in New Issue
Block a user