- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 Flow 而不是 LiveData 来收集 Fragment 中的数据。在 fragment A 中,我观察(或者更确切地说收集) fragment 的 onViewCreated 中的数据,如下所示:
lifecycleScope.launchWhenStarted {
availableLanguagesFlow.collect {
languagesAdapter.setItems(it.allItems, it.selectedItem)
}
}
问题 .然后当我去 Fragment B 然后回到 Fragment A 时,我的 collect 函数被调用了两次。如果我再次去 Fragment B 并返回 A - 那么 collect 函数被调用 3 次。等等。
最佳答案
原因
这是因为 tricky Fragment lifecycle .当您从 fragment B 回到 fragment A 时, fragment A 会重新连接。结果 fragment 的 onViewCreated 被第二次调用,您观察到相同的 Flow 实例 第二次 .换句话说,现在您有一个带有两个观察者的 Flow,当该流发出数据时,会调用其中的两个。
fragment 解决方案1
使用查看生命周期所有者 在 Fragment 的 onViewCreated 中。更具体的使用 查看生命周期所有者 .lifecycleScope.launch 而不是 lifecycleScope.launch。像这样:
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
availableLanguagesFlow.collect {
languagesAdapter.setItems(it.allItems, it.selectedItem)
}
}
Activity 解决方案 2
lifecycleScope.launchWhenStarted {
availableLanguagesFlow.collect {
languagesAdapter.setItems(it.allItems, it.selectedItem)
}
}
附加信息
fun <T> Flow<T>.launchWhenStarted(lifecycleOwner: LifecycleOwner) {
lifecycleOwner.lifecycleScope.launchWhenStarted {
this@launchWhenStarted.collect()
}
}
在 fragment onViewCreated 中:
availableLanguagesFlow
.onEach {
//update view
}.launchWhenStarted(viewLifecycleOwner)
更新
repeatOnLifecycle
, 因为它
取消正在进行的协程 当生命周期低于状态时(在我的例子中是 onStop)。在没有
repeatOnLifecycle
的情况下, onStop 时会暂停收集。查看
this article .
fun <T> Flow<T>.launchWhenStarted(lifecycleOwner: LifecycleOwner)= with(lifecycleOwner) {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED){
try {
this@launchWhenStarted.collect()
}catch (t: Throwable){
loge(t)
}
}
}
}
关于android - 从 Fragment 返回时,Flow onEach/collect 被多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67422182/
我正在尝试使用 DataStore 存储值。 class BasicDataStore(context: Context) : PrefsDataStore( context,
想象一下下面的自包含测试用例 @Test fun `stateFlow in GlobalScope`() = runBlockingTest { suspend fun makeHeavyR
想象一下下面的自包含测试用例 @Test fun `stateFlow in GlobalScope`() = runBlockingTest { suspend fun makeHeavyR
我使用 Flow 而不是 LiveData 来收集 Fragment 中的数据。在 fragment A 中,我观察(或者更确切地说收集) fragment 的 onViewCreated 中的数据,
我是一名优秀的程序员,十分优秀!