让我们把这个简单化。我的 ViewModel
中有一个名为 sortOrder
的 MutableSharedFlow
。
private val sortOrder = MutableSharedFlow<String>(
replay = 0,
extraBufferCapacity = 1
)
我有一个 mapLatest
连接到 sortOrder
以在 sortOrder
更改时刷新数据。
val data = sortOrder.mapLatest {
Timber.d("Sort order changed to $it")
"Sort order is $it"
}
我有一个观察者在 Activity 中监听数据
。
viewModel.data.asLiveData().observe(this) {
Timber.d("onCreate: New data is $it")
}
最后,我更改了 ViewModel
的 init
方法中的 sortOrder
init {
sortOrder.tryEmit("year")
}
但即使在更改 sortOrder
值之后,mapLatest
也不会被触发。知道为什么吗?
我正在使用 MutableSharedFlow
来控制 replay
属性,以防止每次旋转屏幕时(或重新创建 Activity 时)执行 mapLatest
正文).
完整源代码
- 完整 Activity :TestActivity.kt
- 全 View 模型:TestViewModel.kt
PS: I am new to Flow APIs
最佳答案
问题似乎是您发送到流并从中收集的顺序(使用 viewModel.data.asLiveData().observe(...)
)。由于您在 View 模型的构造中发出(使用 tryEmit
),因此您无法在此时进行观察。理论上的实现与此相同:
val sortOrder = MutableSharedFlow<String>(
replay = 0,
extraBufferCapacity = 1
)
val data = sortOrder.mapLatest {
Timber.d("Sort order changed to $it")
"Sort order is $it"
}
sortOrder.tryEmit("year")
data.asLiveData().observe(this) {
Timber.d("onCreate: New data is $it")
}
解决方案取决于您想要的行为:
如果您同意可能将相同的值发送给新的收集器,您可以简单地设置 reply = 1
(然后可以将 extraBufferCapacity
设置为 0
).
另一个解决方案是确保 tryEmit
在 viewModel.data.asLiveData().observe(...)
被调用之前不被调用,并确保该 Activity 至少在 resumed state当调用 tryEmit
时,否则该值将被忽略。
关于android - 共享流 : mapLatest not getting triggered,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65633219/