flow,channelflow,callbackflow初体验

flow在api文档中给了一个使用例子

    fun fibonacci(): Flow<BigInteger> = flow {
        var x = BigInteger.ZERO
        var y = BigInteger.ONE
        while (true) {
            println("fibonacci while $x")
            emit(x)
            x = y.also {
                y += x
            }
        }
    }

测试

fun testJob(){
       testJob=  viewModelScope.launch {
           var i=0
            repository.fibonacci().take(100).collect{
                i++
                println("fibonacci $it")
                println("fibonacci $i")
            }
        }

    }

take表示当消费了100个元素之后,flow将取消。

可以看到 while循环里的代码也只是打到100就结束了。

API文档里面还有说到 flow 中的emit只能严格的在block所在的dispatcher中执行,来维持flow的上下文,即我们不能再flow中切换dispatcher。

flow {
     emit(1) // Ok     
     withContext(Dispatcher. IO) { 
        emit(2) // Will fail with ISE 

    } 
}

当我们需要切换并行发送元素的时候,怎么办呢,有了channelflow,

 
 * fun <T> Flow<T>.merge(other: Flow<T>): Flow<T> = channelFlow {
 *     // collect from one coroutine and send it
 *     launch {
 *         collect { send(it) }
 *     }
 *     // collect and send from this coroutine, too, concurrently
 *     other.collect { send(it) }
 * }

channelflow提供了一个缓冲区域,

channelflow还可以保持开放,正常情况下在 channelFlow lambda执行结束后,通道将关闭。

但是如果调用了 awaitClose ,通道保持开放,直到调用了channel 的close。

send、trySend和trySendBlocking都是用于向Channel中发送数据的方法,但它们在使用方式和行为上有所不同:

‌send方法‌:

send方法用于向Channel发送数据。如果Channel未满,数据会被立即发送;如果Channel已满,发送操作会阻塞,直到Channel有可用空间为止。
示例代码:channel.send(value)
‌trySend方法‌:

trySend方法尝试发送数据到Channel中,如果发送成功则返回true,如果Channel已满则立即返回false,而不会阻塞。
示例代码:if (channel.trySend(value)) { /* 成功发送 */ } else { /* 发送失败 */ }
‌trySendBlocking方法‌:

trySendBlocking方法尝试发送数据到Channel中,如果发送成功则返回true,如果Channel已满则会阻塞当前协程,直到Channel有可用空间为止。
示例代码:if (channel.trySendBlocking(value)) { /* 成功发送 */ } else { /* 发送失败 */ }
‌补充说明‌:

ChannelFlow默认带有64个缓存区,这意味着在大多数情况下,数据可以立即被缓存并异步处理

callbackflow的话,相当于是channelflow的子集,强制运行 awaitclose,这对于需要取消注册,资源清理的时候很有用

 fun networkAvailability(context: Context) = callbackFlow {

        val callback = object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                super.onAvailable(network)
                trySend(true)
            }

            override fun onLost(network: Network) {
                super.onLost(network)
                trySend(false)
            }
        }
        val manager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        //注册
        manager.registerNetworkCallback(
            NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .build(), callback
        )
        awaitClose {
            //取消注册
            manager.unregisterNetworkCallback(callback)
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值