“正在执行某事”的唯一时间是应用程序启动时,而不是名称添加到 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)
}
}
感谢您的阅读!
_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 }
}
}