Flow

介绍:Flow是google官方提供的一套基于kotlin协程的数据流处理模型,类似RxJava。另外Flow作用在协程内,可以与协程的生命周期绑定,当协程取消时,Flow也会被取消,避免了内存泄漏风险,这点又类似LiveData。因此Flow可以用来替代LiveData和RxJava
LiveData不支持线程切换,数据更新都是在主线程完成,对于频繁切换线程处理比较麻烦。
RxRava操作符较多,入门门槛较高,另外未关联生命周期,需要自己处理取消订阅。
使用:
1、创建flow

//方式1
val flowOne = flow {
   for (i in 1..5) {
       emit(i)
   }
}

//方式2
val flowTwo = flowOf(1..5)

//方式3
val flowThree = (1..5).asFlow()

//方式4
val flowFour = channelFlow  {
   for (i in 1..5) {
       send(i)
   }
}

注:方式2、3指定了数据类型,而方式1、4为指定类型可以发送不同类型的数据。

2、执行flow

CoroutineScope(Dispatchers.Main).launch {
    flow {
        for (i in 1..2) {
            Log.e("aa", "emit $i start")
            delay(2000)
            emit(i)
            Log.e("aa", "emit $i end")
        }
        emit("巴拉巴拉!")
    }.onStart {
        Log.e("aa", "onStart")
    }.onCompletion {
        Log.e("aa", "onCompletion")
    }.collect {
        //接收数据流
        Log.e("aa", "collect $it start")
        delay(2000)
        Log.e("aa", "collect $it end")
    }
}

注:

(1)collect要在协程中调用或者把方法用suspend声明为挂起函数

(2)当调用collect时才执行数据流,每个订阅者都完整的执行flow流

(3)flow和collect交叉执行。flow中执行到emit时跳转到collect中执行,collect执行完又回到flow

3、flowOn操作符:指定flow执行环境,不指定默认和collect一致

.flowOn(Dispatchers.IO)

注:

(1)flowOf(requestData()),其中requestData()运行环境与flowOn指定的环境无关,flowOn作用域为flow{}中的代码。

(2)flow{}中不允许通过withContext(Dispatchers.Default) 切换环境需要flowOn方式

4、zip操作符:进行两个流的数据压缩

 val flowOne = flow {
     for (i in 5..10) {
        Log.e("aa", "emit $i start")
        emit(i)
        Log.e("aa", "emit $i end")
     }
 }

....
.zip(flowOne){t1, t2 ->
     "t1=$t1  t2=$t2"
}.collect {
     //接收数据流
     Log.e("aa", "collect $it start")
     delay(2000)
     Log.e("aa", "collect $it end")
}

注:

(1)flow和collect并不像上面那样规律的顺序交叉执行

(2)两个flow中emit的数量不同时,依据最小的执行完为止

5、冷流vs热流(以上创建方式均为冷流,下面介绍热流)

冷流:当订阅时才执行,且每次订阅上游都会完整的执行数据流,相当于每个订阅的事件都是独立的
热流:不管是否被订阅,上游发布都会执行数据流,多个订阅者都能收到相同的消息,相当于将处理结果广播给所有订阅者。

6、SharedFlow

7、StateFlow

参考:
“再见RxJava,你好Flow”,Android线程切换哪家最强?
Android Kotlin之Flow数据流  

注意:如果在同一个协成里订阅了多个热流,只有第一个才会被收集。其他的永远不会得到数据。

所以,要在同一个协程里订阅多个热流可以使用combine或者zip操作符合成到同一个流里。或者开启多个协程分别订阅热流。

例如:

coroutineScope.launch {
    hotFlow1.collect { value ->
        // 可以执行
    }
    hotFlow2.collect { value ->
        // 永远不会执行
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值