文章目录

  • 一、使用 Flow 异步流持续获取不同返回值
  • 二、Flow 异步流获取返回值方式与其它方式对比
  • 三、在 Android 中 使用 Flow 异步流下载文件

一、使用 Flow 异步流持续获取不同返回值


在上一篇博客 【Kotlin 协程】Flow 异步流 ① ( 以异步返回返回多个返回值 | 同步调用返回多个值的弊端 | 尝试在 sequence 中调用挂起函数返回多个返回值 | 协程中调用挂起函数返回集合 ) 中 分析了 以异步方式 分别使用 序列 和 集合 返回多个返回值 ,

  • 序列可以先后返回多个返回值 , 但是会阻塞线程 ;
  • 集合可以一次性返回多个返回值 , 无法持续返回返回值 ;

本篇博客中开始引入 Flow 异步流的方式 , 持续性返回多个返回值 ;

调用 flow 构建器 , 可创建 Flow 异步流 , 在该异步流中, 异步地产生指定类型的元素 ;

public fun <T> flow(@BuilderInference block: suspend FlowCollector<T>.() -> Unit): Flow<T> = SafeFlow(block)

在 flow 异步流构建器中 , 通过调用 FlowCollector#emit 生成一个元素 ; 函数原型如下 :

/*** [FlowCollector]用作流的中间或终端收集器,并表示接收[Flow]发出的值的实体。* 该接口通常不应该直接实现,而是在实现自定义操作符时作为[flow]构建器中的接收器使用。* 这个接口的实现不是线程安全的。*/
public interface FlowCollector<in T> {/*** 收集上游发出的值。* 此方法不是线程安全的,不应该并发调用。*/public suspend fun emit(value: T)
}

调用 Flow#collect 函数, 可以获取在异步流中产生的元素 , 并且该操作是异步操作, 不会阻塞调用线程 ;

public interface Flow<out T> {/*** 接收给定的[collector]并[发出][FlowCollector]。向它发射]值。* 永远不应该实现或直接使用此方法。** 直接实现“Flow”接口的唯一方法是扩展[AbstractFlow]。* 要将它收集到特定的收集器,可以使用' collector. emitall (flow) '或' collect{…}的扩展* 应该使用。这样的限制确保了上下文保存属性不被侵犯,并防止了大多数情况* 与并发性、不一致的流调度程序和取消相关的开发人员错误。*/@InternalCoroutinesApipublic suspend fun collect(collector: FlowCollector<T>)
}

代码示例 :

package kim.hsl.coroutineimport android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlockingclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 携程中调用挂起函数返回一个 Flow 异步流runBlocking {// 调用 Flow#collect 函数, 可以获取在异步流中产生的元素flowFunction().collect {// 每隔 500ms 即可拿到一个 Int 元素// 并且该操作是异步操作, 不会阻塞调用线程println(it)}}}/*** 使用 flow 构建器 Flow 异步流* 在该异步流中, 异步地产生 Int 元素*/suspend fun flowFunction() = flow<Int> {for (i in 0..2) {// 挂起函数 挂起 500ms// 在协程中, 该挂起操作不会阻塞调用线程, 会继续执行其它代码指令// 500ms 恢复执行, 继续执行挂起函数之后的后续代码指令delay(500)// 每隔 500ms 产生一个元素// 通过调用 FlowCollector#emit 生成一个元素emit(i)}}
}

执行结果 : 调用 Flow 异步流 , 可以持续地获取多个返回值 ; 3 个返回值间隔 500 ms 返回给了调用者 ;

2022-12-22 14:55:57.883 9026-9026/kim.hsl.coroutine I/System.out: 0
2022-12-22 14:55:58.423 9026-9026/kim.hsl.coroutine I/System.out: 1
2022-12-22 14:55:58.961 9026-9026/kim.hsl.coroutine I/System.out: 2

二、Flow 异步流获取返回值方式与其它方式对比


Flow 异步流获取返回值方式与其它方式对比 :

① 异步流构建方式 : Flow 异步流是通过 flow 构建器函数 创建的 ;

public fun <T> flow(@BuilderInference block: suspend FlowCollector<T>.() -> Unit): Flow<T> = SafeFlow(block)

② 构建器可调用挂起函数 : flow 构建器代码块中的代码 , 是可以挂起的 , 可以在其中调用 挂起函数 , 如 kotlinx.coroutines.delay 函数等 ;

    /*** 使用 flow 构建器 Flow 异步流* 在该异步流中, 异步地产生 Int 元素*/suspend fun flowFunction() = flow<Int> {for (i in 0..2) {// 挂起函数 挂起 500ms// 在协程中, 该挂起操作不会阻塞调用线程, 会继续执行其它代码指令// 500ms 恢复执行, 继续执行挂起函数之后的后续代码指令delay(500)// 每隔 500ms 产生一个元素// 通过调用 FlowCollector#emit 生成一个元素emit(i)}}

③ suspend 关键字可省略 : 返回值为 Flow 异步流的函数 , 其默认就是 suspend 挂起函数 , suspend 关键字可以省略 , 上述函数中不标注 suspend 也可 ;

    /*** 使用 flow 构建器 Flow 异步流* 在该异步流中, 异步地产生 Int 元素*/fun flowFunction() = flow<Int> {for (i in 0..2) {// 挂起函数 挂起 500ms// 在协程中, 该挂起操作不会阻塞调用线程, 会继续执行其它代码指令// 500ms 恢复执行, 继续执行挂起函数之后的后续代码指令delay(500)// 每隔 500ms 产生一个元素// 通过调用 FlowCollector#emit 生成一个元素emit(i)}}

④ 生成元素 : 在 Flow 异步流中 , 通过调用 FlowCollector#emit 函数生成元素 ;

⑤ 收集元素 : 在 Flow 异步流中 , 通过调用 Flow#collect 函数可以收集 在 Flow 异步流中生成的元素 ;

三、在 Android 中 使用 Flow 异步流下载文件


Android 中主线程不可执行网络相关操作 , 因此只能在 子线程 中下载文件 ,

可以在协程中使用 Dispatcher.IO 调度器在子线程下载文件 ,

下载文件时需要实时显示下载百分比进度 ,

这个进度需要上报给主线程 , 在主线程中更新 UI 显示下载进度 ,

在 Flow 异步流中 , 可以 使用 FlowCollector#emit 向主线程中发送进度值 ,

在主线程中 , 可以 使用 Flow#collect 函数 收集 Flow 异步流中发射出来的数据 , 如 : 进度 , 捕获的异常 , 下载状态等 ;

完整流程 , 如下图所示 :

【Kotlin 协程】Flow 异步流 ② ( 使用 Flow 异步流持续获取不同返回值 | Flow 异步流获取返回值方式与其它方式对比 | 在 Android 中使用 Flow 异步流下载文件 )相关推荐

  1. 【Kotlin 协程】Flow 异步流 ④ ( 流的构建器函数 | flow 构建器函数 | flowOf 构建器函数 | asFlow 构建器函数 )

    文章目录 一.流的构建器函数 1.flow 构建器 2.flowOf 构建器 3.asFlow 构建器 一.流的构建器函数 1.flow 构建器 在之前的博客 [Kotlin 协程]Flow 异步流 ...

  2. Kotlin 协程是个什么东西?

    相关阅读:一个90后员工猝死的全过程 协程是什么 根据维基百科的定义,协程(Coroutine)是计算机程序的一类组件,推广了协作式多任务的子程序,允许执行被挂起与被恢复. 协程(Coroutine) ...

  3. 【Kotlin 协程】Flow 异步流 ⑤ ( 流的上下文 | 上下文保存 | 查看流发射和收集的协程 | 不能在不同协程中执行流的发射和收集操作 | 修改流发射的协程上下文 | flowOn函数 )

    文章目录 一.流的上下文 1.上下文保存 2.流收集函数原型 3.流发射函数原型 4.代码示例 - 查看流发射和收集的协程 5.代码示例 - 不能在不同协程中执行相同流的发射和收集操作 二.修改流发射 ...

  4. 大型Android项目架构:基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid客户端

    前言:苟有恒,何必三更眠五更起:最无益,莫过一日曝十日寒. 前言 之前一直想写个 WanAndroid 项目来巩固自己对 Kotlin+Jetpack+协程 等知识的学习,但是一直没有时间.这里重新行 ...

  5. Kotlin 协程Flow、StateFlow、ShareFlow

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

  6. Kotlin 协程Flow主要操作符(一)

    Kotlin 协程Flow主要操作符(一) 1. 主要导包 2. map 转换操作符 3. filter过滤操作符 4. take限长操作符 5. drop丢弃操作符 6. flowOn操作符 7. ...

  7. 深潜Kotlin协程(二十一):Flow 生命周期函数

    系列电子书:传送门 Flow 可以想象成一个管道,请求的值在一个方向上流动,而相应产生的值在另一个方向上流动.当 flow 完成或出现异常时,这些信息也会被传递,并关闭途中的中间步骤.因此,当这些值开 ...

  8. kotlin协程_Kotlin协程

    kotlin协程 In this tutorial, we'll be looking into Kotlin Coroutines. Coroutines is a vital concept si ...

  9. Kotlin协程:协程的基础与使用

    一.协程概述 1.概念 协程是Coroutine的中文简称,co表示协同.协作,routine表示程序.协程可以理解为多个互相协作的程序.协程是轻量级的线程,它的轻量体现在启动和切换,协程的启动不需要 ...

最新文章

  1. 数据丢失如当头棒喝,数据备份重如山!
  2. 结构 win32_COM编程攻略(十五 持久化与结构化存储)
  3. angularJs 跨控制器与跨页面传值
  4. css行高line-height的一些深入理解及应用
  5. POJ 1821 单调队列+dp
  6. 初始化JQuery方法与(function(){})(para)匿名方法介绍
  7. POJ - 1226 Substrings(后缀数组+二分)
  8. javascript保留两位
  9. 使用 SDK (Nodejs)操作阿里 OSS (对象存储服务)学习笔记
  10. 水电缴费系统php源码_php简易扫码付教育收费系统 v1.2
  11. 基于国产全志A40I的机器人示教器解决方案
  12. python 服务器和客户端 学习http请求和响应报文头
  13. 怎样删除usb计算机连接网络打印机驱动,打印机USB连接安装设置及常见问题处理...
  14. win11自带的照片查看器无法打印问题解决
  15. WPF应用无法使用Snoop分析的解决办法
  16. 欧拉定理(Tetration,玲珑杯 Round#5 E lonlife 1060)
  17. 3DsMax游戏模型制作技巧,掌握这些技术你也能接私活啦
  18. MAC Safari 浏览器自动重启,活动监视器闪退,CPU过高导致风扇嗡嗡响
  19. WINDOW -- 给硬盘分盘以及合盘
  20. 计算机毕业设计ssm校园竞赛管理系统设计与实现hyr9b系统+程序+源码+lw+远程部署

热门文章

  1. C语言将华氏温度转为摄氏度
  2. python 断点_断点python_python 断点_python断点定义 - 云+社区 - 腾讯云
  3. cmder linux ssh,Terminus:一款不错的SSH软件,适用于Windows、macOS和Linux系统
  4. 程序人生 | (8) 好的研究想法从哪里来
  5. Servlet下载文件迅雷不支持问题真相之一
  6. 世界类脑AI巨系统研究综述,论ET大脑是不是全球首个类脑架构AI
  7. 医药之家:医疗器械龙头企业排名变动,11家中国企业入选全球百强!
  8. 计算机信息加工是指什么作用,什么是信息加工信息加工的方式
  9. 解决android代码编译时内存不足
  10. 苹果电脑python官网下载步骤-Python3 Mac版下载