2

安卓、科特林

我的数据源类中有以下实时数据,我无法将其更改为 StateFlow,因此需要在我的 viewModel 中将其转换为 StateFlow

val trackingCatalogInitialLoadLiveData: LiveData<Pair<CatalogTracking, Int>> by lazy {
    instantSearchDataSourceLiveData.switchMap { instantSearchDataSource ->
        instantSearchDataSource.initialLoadLiveData
    }
}

在我的 ViewModel 中,我有以下内容,这是我不确定这是否是将 LiveData 转换为 StateFlow 的正确方法的部分:

 val trackingCatalogInitialLoadStateFlow: StateFlow<Pair<CatalogTracking, Int>> by lazy {
        instantSearchDataSourceFactory.trackingCatalogInitialLoadLiveData.asFlow()
            .stateIn(viewModelScope, SharingStarted.Lazily, Pair(CatalogTracking(), 0))
    }

然后在我的片段中,我只收集结果

coroutineScope.launch {
        mInstantSearchViewModel.trackingCatalogInitialLoadStateFlow.collect { trackingPair ->
           // code here
    }

这是将 LiveData 转换为 StateFlow 的最佳实践吗?有什么我应该注意的吗?

4

1 回答 1

1

你不需要使用by lazy. asFlow()并且stateIn()都创建了简单的包装器,因此直接在属性初始化程序中调用它们很简单。

正如@Joffrey 所说,如果您使用,在有任何收集器之前SharingStarted.Lazily检查流将错误地显示您提供的初始值。value由于 LiveData 很热门,因此懒惰地启动 StateFlow 不会给您带来很多好处。将 LiveData 值传输到 StateFlow 的底层协程正在做一些微不足道的工作。

如果您不需要检查value(在大多数情况下您可能不需要),那么将其保留为冷流应该没问题。即使 Flow fromasFlow()是冷的,底层的 LiveData 仍然是热的,所以当流的收集器收集它时,他们总是会得到最新的值。主要的行为差异是,如果您的数据源没有为 LiveData 提供有保证的初始值,那么 StateFlow 让您有机会在初始时发出您提供的默认值,而无需等待 LiveData 发布其第一个值。

于 2022-02-22T15:42:26.930 回答