当前位置: 首页 > news >正文

Kotlin Flow 完全指南

Kotlin Flow 完全指南

一、Flow 到底是什么

一句话:Flow = Kotlin 的"异步数据流"

它是:协程版 RxJava

但:

  • 更轻量
  • 更简单
  • 更符合 Kotlin 风格

你可以把 Flow 理解成:“会持续发数据的管道”

比如:

  • 网络请求状态
  • 输入框搜索
  • 倒计时
  • WebSocket
  • 数据库变化
  • 页面状态更新

这些都不是:只返回一次,而是:持续产生数据

这就是:Flow 的核心


二、先用最容易理解的例子

普通函数

fungetData():String{return"hello"}

只能返回一次:hello→ 结束

Flow

fungetFlow()=flow{emit("hello")delay(1000)emit("world")}

它会:hello→ 1秒后 →world

也就是:可以连续发送数据


三、最核心的两个东西

Flow 只有两个关键点:

方法作用
emit()发送数据
collect()接收数据
flow.collect{}

四、第一个完整 Flow

创建

valflow=flow{emit(1)emit(2)emit(3)}

收集

lifecycleScope.launch{flow.collect{println(it)}}

输出:

1 2 3

五、为什么必须在协程里 collect

因为:Flow 是挂起的

collect本质是suspend fun collect()

所以必须:launch或在suspend函数里调用。


六、Flow 执行流程(超重要)

很多人学不会就是这里没懂。

Flow 是"冷流"—— 你不 collect,它就不执行。

valflow=flow{println("开始")emit(1)}

此时:什么都不会打印,因为没人收集。

collect后:

flow.collect()

才会输出:开始1


七、最经典 Android 场景

场景1:网络请求状态

这是实际项目最多的。

不使用 Flow

funlogin(callback:Callback)

回调地狱。

Flow 版本

funlogin()=flow{emit(Loading)valresult=api.login()emit(Success(result))}

页面:

lifecycleScope.launch{viewModel.login().collect{when(it){isLoading->showLoading()isSuccess->showData()}}}

这就是:MVVM + Flow,现代 Android 标配。


八、StateFlow(真正项目核心)

实际项目用最多的不是 Flow,而是:StateFlow

因为 UI 需要:

  • 始终持有最新状态

九、StateFlow 最容易理解方式

它像:LiveData 升级版

但:

  • 协程化
  • 更强
  • 更快
  • 支持 Flow 全家桶

十、最经典 StateFlow

ViewModel

classMainViewModel:ViewModel(){privateval_state=MutableStateFlow("默认值")valstate=_state.asStateFlow()funupdate(){_state.value="新数据"}}

页面监听

lifecycleScope.launch{viewModel.state.collect{tv.text=it}}

StateFlow 最大特点:永远有值

MutableStateFlow("默认值")

必须给初始值,因为它代表:当前状态


十一、为什么 Google 推荐 StateFlow 替代 LiveData

特性StateFlowLiveData
协程支持
操作符超多很少
Kotlin 化完全一般
冷热流支持支持不支持
性能更强一般
官方趋势主推逐渐弱化

十二、实际项目最常见结构:UIState

现代 Android 必会。

定义状态

sealedclassUIState{objectLoading:UIState()dataclassSuccess(valdata:String):UIState()dataclassError(valmsg:String):UIState()}

ViewModel

privateval_uiState=MutableStateFlow<UIState>(UIState.Loading)valuiState=_uiState.asStateFlow()// 更新状态viewModelScope.launch{try{valresult=api.getData()_uiState.value=UIState.Success(result)}catch(e:Exception){_uiState.value=UIState.Error("失败")}}

页面

lifecycleScope.launch{viewModel.uiState.collect{when(it){isUIState.Loading->{/* show loading */}isUIState.Success->{/* show data */}isUIState.Error->{/* show error */}}}}

十三、SharedFlow 是什么

一句话:可广播事件流

  • StateFlow:保存状态
  • SharedFlow:发送事件

十四、最经典场景:Toast

Toast:一次性事件,不应该保存状态。

SharedFlow

privateval_event=MutableSharedFlow<String>()valevent=_event// 发送_event.emit("登录成功")// 页面collect{Toast.makeText(context,it,Toast.LENGTH_SHORT).show()}

十五、为什么 Toast 不能用 StateFlow

因为 StateFlow 会记住最后一个值。

旋转屏幕后:Toast 又弹一次

这就是经典的LiveData Event 问题,SharedFlow 可以避免。


十六、Flow 最重要操作符

map — 数据转换

flow.map{it*2}

filter — 过滤

flow.filter{it>10}

debounce(Android 超常用)— 防抖

搜索框神器:

editTextFlow.debounce(500)// 停止输入500ms后才搜索

十七、搜索框实战(面试高频)

editTextFlow.debounce(500).distinctUntilChanged().collect{search(it)}
操作符含义
debounce停止输入再搜索,避免疯狂请求
distinctUntilChanged内容没变不重复搜索

十八、flatMapLatest(巨重要)

这是:Flow 灵魂操作符

场景:用户快速搜索aababcabcd,你希望只保留最后一次请求。

queryFlow.flatMapLatest{repository.search(it)}

效果:

  • 旧请求:自动取消
  • 只保留:最新请求

十九、Android 搜索框完整实战

searchFlow.debounce(300).distinctUntilChanged().flatMapLatest{repository.search(it)}.flowOn(Dispatchers.IO).collect{adapter.submitList(it)}

二十、flowOn 是什么

切线程:

flow{emit(api.getData())}.flowOn(Dispatchers.IO)

表示:上游在 IO 线程

collect默认在当前协程线程,通常是Main


二十一、catch 异常处理

flow{emit(api.getData())}.catch{emit(emptyList())}

二十二、onStart — 开始加载

flow.onStart{showLoading()}

二十三、onCompletion — 结束

flow.onCompletion{hideLoading()}

二十四、Room 为什么天然支持 Flow

@Query("SELECT * FROM users")fungetUsers():Flow<List<User>>

数据库变化:自动通知 UI

这是:响应式数据库


二十五、Compose 为什么和 Flow 天生搭配

  • Compose:状态驱动 UI
  • Flow:状态流

天然适配:

valstatebyviewModel.state.collectAsState()

UI 自动刷新。


二十六、Flow vs LiveData

对比FlowLiveData
协程支持
操作符超多很少
Kotlin 化完全一般
冷热流支持支持不支持
性能更强一般
官方趋势主推逐渐弱化

二十七、Flow vs RxJava

对比FlowRxJava
学习成本
Kotlin 支持官方一般
操作符数量中等超多
Android 官方主推非主推
协程融合原生不自然

二十八、项目里真正怎么用

现代 Android 通常:

  1. Repository 返回 Flow:fun getData(): Flow<Data>
  2. ViewModel 转 StateFlow:MutableStateFlow
  3. UI collect
  4. repeatOnLifecycle

二十九、repeatOnLifecycle(非常重要)

错误写法

launch{flow.collect{}}

页面退出可能还在收集。

正确写法

lifecycleScope.launch{repeatOnLifecycle(Lifecycle.State.STARTED){flow.collect{}}}
  • 页面不可见:自动停止
  • 页面回来:自动恢复

三十、Android 项目最佳实践结构

Repository

fungetUser()=flow{emit(api.getUser())}

ViewModel

valuiState=repository.getUser().stateIn(viewModelScope,SharingStarted.WhileSubscribed(),UIState.Loading)

Activity/Fragment

repeatOnLifecycle(Lifecycle.State.STARTED){viewModel.uiState.collect{}}

三十一、最容易记忆的一张图

Flow ├── 数据流 ├── emit → 发数据 └── collect → 收数据 StateFlow → 保存状态 SharedFlow → 发送事件 flatMapLatest → 只保留最新请求 debounce → 防抖 flowOn → 切线程

三十二、面试高频回答模板

如果面试问:Flow 有什么用?

可以这样答:

Flow 是 Kotlin 协程提供的异步数据流,用于替代传统 Callback、LiveData、部分 RxJava。

Flow 支持:持续数据发送、协程挂起、操作符链式调用、线程切换、异常处理。

Android 项目中:通常 Repository 返回 Flow,ViewModel 使用 StateFlow 管理 UI 状态,SharedFlow 处理一次性事件。

常见场景:网络请求、搜索防抖、Room 数据监听、Compose 状态更新、WebSocket、分页加载。

Google 官方目前推荐:Flow + StateFlow作为现代 Android 响应式方案。

http://www.jsqmd.com/news/811264/

相关文章:

  • 基于OpenClaw的iPad本地AI应用开发:架构设计与工程实践
  • 告别抓瞎!手把手教你用vConsole调试移动端H5页面(附Vue项目实战配置)
  • AntiDupl.NET:高效智能的重复图片检测与清理解决方案
  • 告别安卓模拟器:5步在Windows系统直接安装APK应用的终极方案
  • 保姆级教程:在Win10上用VS2022搞定TensorRT 8.5.2.2(含zlibwapi.dll缺失等常见坑点)
  • 在OpenClaw项目中配置Taotoken作为核心模型供应商
  • Midjourney v8图像修复黑盒逆向报告:基于2,147次A/B测试,揭示--fix、--reroll、--refine三指令响应延迟差异达412ms
  • [算法训练] LeetCode Hot100 学习笔记#23
  • 机器学习知识产权保护:从数据到模型的立体防御策略
  • 智能手机如何重塑芯片市场:从基带到SoC的平台化竞争
  • iPhone安全诊断:从异常耗电到系统排查的工程实践指南
  • 3款精选工具:重新定义你的星露谷物语体验
  • Midjourney Mega计划权限体系完全手册(含角色继承漏洞、跨工作区资产迁移失败率TOP3归因分析)
  • WarcraftHelper:免费终极指南,让魔兽争霸III在现代系统上流畅运行
  • Python 爬虫进阶技巧:爬虫日志记录异常捕获与错误复盘
  • 如何快速使用开源字体Poppins:面向设计师的完整免费几何字体指南
  • STM32L4 RTC唤醒中断实战:用CubeIDE配置30秒低功耗定时,实测两种模式差异
  • 极域电子教室破解终极指南:5步重获电脑控制权
  • Linux串口编程避坑指南:termios结构体那些容易配错的标志位(附调试技巧)
  • LTE信令流程:从协议基石到网络交互的实战解析
  • DeepSeek DevOps可观测性升级方案(埋点、链路、指标三位一体,附Prometheus+OpenTelemetry配置速查表)
  • 客观现实源于波函数坍缩:意识内源测量与智能外源投影一体化统一理论(世毫九实验室原创理论)
  • HC32F460_ADC驱动(二)
  • Poppins开源字体:现代几何设计的跨平台无障碍实践终极指南
  • 如何用ComfyUI MixLab插件重塑你的AI创作流程:5个颠覆性应用场景
  • 南洋理工大学、山东大学等机构联合提出的多模态搜索新范式
  • Windows 11 HiDPI光标优化:Capitaine主题安装与深度定制指南
  • 可穿戴示波器的安全隐患与工程安全设计思考
  • 终极图像去重神器:用AntiDupl.NET轻松清理重复图片的完整指南
  • Python 爬虫进阶技巧:爬虫断点续传中断后继续采集数据