问题描述
如果更新的值等于旧值 (source),
MutableStateFlow
不会通知收集器。我为此找到了一个 workaround,但它不能很好地适应复杂的值。
解决方法:使用 copy()
复制数据类并使用 toList()
/toMutableList()
复制列表。
示例 1:使用变通方法重命名 WorkoutRoutine
的简单数据类 name
。这里没有错。
data class WorkoutRoutine(
var name: String,)
val workoutRoutine = MutableStateFlow(WorkoutRoutine("Initial"))
workoutRoutine.value.name = "Updated" // Doesn't notify collectors
workoutRoutine.value = workoutRoutine.value.copy(name = "Updated") // Workaround: works
示例 2:具有多个依赖项的复杂数据类 WorkoutRoutine
,使用变通方法将 Set
添加到 Exercise
中的 WorkoutRoutine
:这需要大量的 {{ 1}} 和 copy()
调用,使代码不可读。
toMutableList()
我尝试了以下方法:
- 添加强制更新
data class WorkoutRoutine( var name: String,var exercises: MutableList<Exercise> = mutablelistof(Exercise()) ) data class Exercise( var sets: MutableList<Set> = mutablelistof(Set()) ) data class Set( var weight: Int? = null ) val workoutRoutine = MutableStateFlow(WorkoutRoutine("Initial")) // Doesn't notify collectors workoutRoutine.value.apply { exercises = exercises.also { it[0].sets.add(Set()) } } // Workaround: works workoutRoutine.value = workoutRoutine.value.copy( exercises = workoutRoutine.value.exercises.toMutableList().also { it[0] = it[0].copy(sets = it[0].sets.apply { add(Set()) }) } )
的扩展值MutableStateFlow.valueNotdistinct
。
-> 问题:MutableStateFlow.value
必须可以为空
MutableStateFlow.value
- 使用
var <T> MutableStateFlow<T?>.valueNotdistinct: T? get() = null set(newValue) { value = null value = newValue }
,它不检查相等性
-> 问题:性能不佳,没有MutableSharedFlow
属性
我想要的是在每次发出时简单地通知收集器,但我不知道该怎么做,因为 MutableStateFlow 似乎没有“强制通知”功能。
解决方法
StateFlow 文档说明了这一点:
基于等式的强合并
状态流中的值使用 Any.equals 比较在一个 类似于 distinctUntilChanged 运算符的方式。它用于合并 传入更新 MutableStateFlow 中的值并抑制发射 当新值等于以前的值时收集器的值 发出了一个。使用违反规则的类的状态流行为 Any.equals 的合同未指定。
解决方法可能是覆盖 equals
方法以始终返回 false
。因此,数据类对您的情况没有帮助。
class WorkoutRoutine() {
...
override fun equals(other: Any?): Boolean {
return false
}
}