调用广播接收器时流程未更新

问题描述 投票:0回答:1
我是 kotlin 新手,正在尝试制作一个课程药物提醒应用程序。 当我的 AlarmReceiver 将新名称添加到当前警报流中时,我的虚拟机没有做出反应。

“正在执行某事”的唯一时间是应用程序启动时,而不是名称添加到 currentAlerts 时。是否可以以这种方式使用流程或者我误解了它们?

medicineViewModel.kt

class MedicineViewModel( private val dao: DatabaseDAO, private val alarmScheduler: AlarmScheduler, alarmReceiver: AlarmReceiver, private val userPreferencesRepository: UserPreferencesRepository, ) : ViewModel() { private val _currentAlerts = alarmReceiver.currentAlertsFlow private val _medicines = combine(dao.getMedicinesByName(), _currentAlerts) { medicines, currentAlerts -> Log.d("medicineViewModel", "${currentAlerts.size}") medicines.map { medicine -> Log.d("medicineViewMode", "doing something! ${medicine.name}") Log.d("medicineViewModel", "${medicine.name}, ${medicine.name in currentAlerts}") medicine.copy(isAlerting = medicine.name in currentAlerts) } }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList()) private val _preferences = userPreferencesRepository.getActivated().stateIn( viewModelScope, SharingStarted.WhileSubscribed(), UserPreferences(activated = false) ) //_state håller koll på allt som visas på skärmen. private val _state = MutableStateFlow(MedicineState()) // Starta ett nytt flow utifrån MedicineState (börjar tomt) // _state är allting som visas på skärmen. Man hämtar medicinerna via DAO och stoppar in det i "medicines" i state. // Allting innan .stateIn är instruktioner för när man börjar löpande hämta data. MedicineState() i stateIn är // utgångspunkten, alltså en tom skärm. val state = combine(_state, _medicines, _preferences) { state, medicines, preferences -> state.copy( medicines = medicines, preferences = preferences, ) }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), MedicineState()) fun onEvent(event: MedicineEvent) { when (event) { ... } } fun calculateAlarms() { for (medicine in state.value.medicines) { val alarmItem = AlarmItem( medicineName = medicine.name, time = LocalDateTime.now() .plusMinutes(medicine.interval.toLong()) ) alarmItem.let(alarmScheduler::schedule) } } }
alarmReceiver.kt

package com.example.myapplication.model.alarm import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow class AlarmReceiver : BroadcastReceiver() { // MutableStateFlow to hold the latest list of alerts private val _currentAlertsFlow = MutableStateFlow(mutableListOf<String>()) val currentAlertsFlow: StateFlow<MutableList<String>> get() = _currentAlertsFlow override fun onReceive(context: Context, intent: Intent?) { Log.d("AlarmReceiver", "alarm triggered!") val message = intent?.getStringExtra("medicineName") ?: return Log.d("AlarmReceiver", "Alarm triggered: $message") // Update the alerts list and emit the new list // val updatedAlerts = _currentAlertsFlow.value.toMutableList() // updatedAlerts.add(message) // _currentAlertsFlow.value = updatedAlerts _currentAlertsFlow.value.add(message) } }
感谢您的阅读!

android kotlin mvvm broadcastreceiver
1个回答
0
投票
你所做的基本上是正确的。只有一个主要问题:StateFlow 仅在设置“new”值时通知其观察者。但这不是你所做的:

_currentAlertsFlow.value.add(message)

这只会
修改
已经存在的值。在这种情况下,最佳实践应该首先阻止此错误的出现:使您的状态对象

不可变_currentAlertsFlow 的内容应为 List<String>

 类型,而不是 
MutableList<String>
AlarmReceiver 应该看起来像这样:

class AlarmReceiver : BroadcastReceiver() { private val _currentAlertsFlow = MutableStateFlow(emptyList<String>()) val currentAlertsFlow: StateFlow<List<String>> get() = _currentAlertsFlow override fun onReceive() { // .. _currentAlertsFlow.update { it + message } } }


© www.soinside.com 2019 - 2024. All rights reserved.