Android 在两个片段之间共享ViewModel中的可变状态流的冷流
两个片段之间共享的MutableStateFlow属性有问题 为了让人理解: 我有一个Android 在两个片段之间共享ViewModel中的可变状态流的冷流,android,kotlin,navigation,viewmodel,flow,Android,Kotlin,Navigation,Viewmodel,Flow,两个片段之间共享的MutableStateFlow属性有问题 为了让人理解: 我有一个BasicViewModel,由于nav图的实现,它应该始终是这两个片段的一个实例 private val basicViewModel: basicViewModel by navGraphViewModels(R.id.basic_graph) { defaultViewModelProviderFactory } 此ViewModel具有如下声明的MutableStateFlow属性 priva
BasicViewModel
,由于nav图的实现,它应该始终是这两个片段的一个实例
private val basicViewModel: basicViewModel by navGraphViewModels(R.id.basic_graph) { defaultViewModelProviderFactory }
此ViewModel具有如下声明的MutableStateFlow
属性
private val _basicProperty = MutableStateFlow<BasicClass?>(null)
val basicProperty : Flow<BasicClass?> = _basicId
.filterNotNull()
.flatMapConcat { someRepository.getBasicProperty(it) }
.onEach { _basicProperty.value = it }
.catch { }
basicViewModel.basicProperty
.filterNotNull()
.mapNotNull { it.innerProperty}
.onEach { doSomething(it) }
.launchIn(viewLifecycleOwner.lifecycleScope)
这一切看起来都很好,但当我导航到FragmentA
基本属性加载流(来自WebApi的数据加载)时,我导航到FragmentB
并再次加载流,而不是调用已经加载的数据,在应用程序中,由于重新加载,它看起来有点滞后
问题:我应该如何做/更改才能从
FragmentB
中的BasicViewModel
获取现有数据?您的\u basicProperty
是一个热门状态流,但您从不使用它来收集任何内容。您已公开的属性,basicProperty
,是一个冷流,因此收集该属性的每个订阅服务器都将启动冷流的新运行。这些冷流中的每一个都会将它们的更新发布到MutableStateFlow,因此在这一点上,它的状态是不可预测的,因为它显示了共享冷流的任何收集器正在做的最新事情
我认为你想要的是有一个共享的执行流程。因此,您应该有一个执行连接的状态流,如下所示:
val basicProperty : StateFlow<BasicClass?> = _basicId
.filterNotNull()
.flatMapConcat { someRepository.getBasicProperty(it) }
.catch { }
.stateIn(viewModelScope, SharingStarted.Eagerly, null)
val基本属性:StateFlow=\u基本属性
.filterNotNull()
.flatMapConcat{someRepository.getBasicProperty(it)}
.catch{}
.stateIn(viewModelScope,SharingStarted.Acquiredly,null)
在每个片段出现并收集之前,您的原始代码不会启动流。但是此代码对stateIn
的调用在viewModelScope
中启动了一次流(在这种情况下,由于急切地使用了参数)
现在这个流只运行一次。您仍然可以让每个片段像您已经做的那样运行自己的下游流。这正是我所需要的。感谢@Tenfour04的回答和精彩的解释。看来我还得多读一些关于Kotlin流量的书。谢谢