Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在两个片段之间共享ViewModel中的可变状态流的冷流_Android_Kotlin_Navigation_Viewmodel_Flow - Fatal编程技术网

Android 在两个片段之间共享ViewModel中的可变状态流的冷流

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

两个片段之间共享的MutableStateFlow属性有问题

为了让人理解:

我有一个
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流量的书。谢谢