Kotlin 协程Flow、StateFlow、ShareFlow

Kotlin 协程Flow、StateFlow、ShareFlow

数据流

数据流以协程为基础构建,可提供多个值。从概念上来讲,数据流是可通过异步方式进行计算处理的一组数据序列。所发出值的类型必须相同。例如,Flow<Int> 是发出整数值的数据流。

 //在Acitivity中创建一个定时数据流并接收
 lifecycleScope.launchWhenResumed {
            flow {
                while (true) {
                    emit(1)
                    delay(1000)
                }
            }.collect {
                
            }
        }

数据流包含三个实体:

  • 提供方会生成添加到数据流中的数据。得益于协程,数据流还可以异步生成数据。
  • 中介可以修改发送到数据流的值,或修正数据流本身。
  • 使用方则使用数据流中的值。

在这里插入图片描述

  1. 流的启动:
 //在作用域里launch
 lifecycleScope.launchWhenResumed {
            flow {
                while (true) {
                    emit(1)
                    delay(1000)
                }
            }.collect {
                
            }
        }
        
//用 launchIn操作符       
 flow {
            while (true) {
                emit(1)
                delay(1000)
            }
        }.onEach{//可在此接收数据
            
        }.launchIn(lifecycleScope)
  1. 流的异常捕获catch
 flow {
            while (true) {
                emit(1)
                delay(1000)
            }
        }.catch {//异常捕获

        }.onEach {

        }.launchIn(lifecycleScope)
  1. 流的开始与完成
flow {
            while (true) {
                emit(1)
                delay(1000)
            }
        }.onStart {//开始

        }.catch {

        }.onEach {

        }.onCompletion {//完成

        }.launchIn(lifecycleScope)

StateFlow

StateFlow 是一个状态容器式可观察数据流,可以向其收集器发出当前状态更新和新状态更新。还可通过其 value 属性读取当前状态值。StateFlow 非常适合需要让可变状态保持可观察的类。与LiveData相似,比它强大,一般搭配协程使用。是热流:从此类数据流收集数据不会触发任何提供方代码。Flow一般是冷流,需要启动提供方发送数据。

比如下面的uiState就是一个状态流

class FileDownloadViewModel : ViewModel() {
	//数据设置
    private val _uiState = MutableStateFlow<FileState>(FileState.DownloadIdle)
    //数据获取
    val uiState: StateFlow<FileState> = _uiState

    //下载文件
    fun downloadFile() {
        flow {
            for (i in 1..100) {
                _uiState.value = FileState.Downloading(i)
                emit(i)
                if (i == 100) {//进度为100时,下载完成
                    _uiState.value = FileState.DownloadSuccess
                }
            }
        }.flowOn(Dispatchers.IO)
            .catch {
                _uiState.value = FileState.DownLoadFail(RuntimeException("下载失败"))
            }.onEach {

            }.launchIn(viewModelScope)
    }

}

sealed class FileState {
    object DownloadIdle : FileState()//未下载
    data class Downloading(val progress: Int) : FileState()//下载中
    object DownloadSuccess : FileState()//下载完成
    data class DownLoadFail(val exception: Throwable) : FileState()//下载失败
}

//在Activity中接收
 viewModel.uiState.onEach { state ->
            when (state) {
                is FileState.DownloadIdle -> {

                }
                is FileState.Downloading -> {

                }
                is FileState.DownloadSuccess -> {

                }
                is FileState.DownLoadFail -> {

                }
            }
        }.launchIn(lifecycleScope)

StateFlow、Flow 和 LiveData

StateFlowLiveData 具有相似之处。两者都是可观察的数据容器类,并且在应用架构中使用时,两者都遵循相似模式。不同:

  • StateFlow 需要将初始状态传递给构造函数,而 LiveData 不需要。
  • 当 View 进入 STOPPED 状态时,LiveData.observe() 会自动取消注册使用方,而从 StateFlow 或任何其他数据流收集数据的操作并不会自动停止。如需实现相同的行为,您需要从 Lifecycle.repeatOnLifecycle 块收集数据流。
  • LiveData的监听需要传入LifecycleOwner,而StateFlow与Flow只需要传入相关的协程作用域即可。

SharedFlow

shareIn 函数会返回一个热数据流 SharedFlow,比如一个Flow调用shareIn方法,会变成SharedFlow。此数据流会向从其中收集值的所有使用方发出数据。SharedFlowStateFlow 的可配置性极高的泛化数据流。

//通过 replay,您可以针对新订阅者重新发送多个之前已发出的值。
    private val _stringFlow = MutableSharedFlow<String>(replay = 0)
    val stringFlow: SharedFlow<String> = _stringFlow
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值