gpt4 book ai didi

android - 在 ViewModel 中收集流。需要repeatOnLifeCycle 吗?

转载 作者:行者123 更新时间:2023-12-04 23:39:36 24 4
gpt4 key购买 nike

到目前为止,我曾经像这样在 Activity/fragment 或 ViewModel 中收集我的流
Activity/fragment

  lifecycleScope.launch {
myViewModel.readTokenCredentials().collect { data -> /* do something */ }
}
View 模型

viewModelScope.launch {
prefsRepo.readTokenCredentials().collect { data -> /* do something */ }
}
现在 Google 开发人员 tell我们认为这不是收集流的安全方法,因为它可能导致内存泄漏。相反,他们建议将集合包装在 lifecycle.repeatOnLifecycle 中。用于 Activity/fragment 中的流收集。
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
myViewModel.readTokenCredentials().collect { data -> /* do something */ }
}
}
我的问题是:
为什么我不能使用 repeatOnLifecycleviewModelScope在 View 模型内收集流时?当然我知道 View 模型不知道生命周期,但可能是 viewModelScope在流收集期间不太可能引入内存泄漏?

最佳答案

由于 ViewModel 没有重复的生命周期,因此不可能重复生命周期。它启动一次,销毁一次。
我不认为内存泄漏是一个准确的术语,即当 fragment 在屏幕外时继续收集流时发生的事情。它只是导致它的上游 Flow 无缘无故地继续发射,但发射的项目将被垃圾收集。这简直是​​浪费 Activity 。如果您也在收集器中更新 UI,那么危险就来了,因为您可能会不小心更新屏幕外的 View 。
在 ViewModel 中,您有无缘无故从 Flows 收集数据的风险。为避免它,您可以使用 stateInshareInWhileSubscribed值(value)。然后当下游没有任何收集时它将停止收集。如果您使用 repeatOnLifecycle在从这些 SharedFlows 和 StateFlows 收集的 Activity 和 fragment 中,一切都得到了照顾。
例如:

val someFlow = prefsRepo.readTokenCredentials()
.map { data -> // doSomething }
.shareIn(viewModelScope, SharingStarted.WhileSubscribed(5000L), 1)
并将其收集在 UI 层。如果 UI 没有什么可收集的,那为什么 Flow 会首先存在呢?我想不出一个好的反例。 ViewModel 旨在准备模型以供查看,而不是做从未见过的工作。

关于android - 在 ViewModel 中收集流。需要repeatOnLifeCycle 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69982729/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com