Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >(StateFlow & ShareFlow) VS (Flow & LiveData)

(StateFlow & ShareFlow) VS (Flow & LiveData)

作者头像
小柔
发布于 2022-10-09 04:26:52
发布于 2022-10-09 04:26:52
1.1K00
代码可运行
举报
文章被收录于专栏:小柔博客园小柔博客园
运行总次数:0
代码可运行

theme: condensed-night-purple highlight: vs

在之前的Flow,collect函数浅析仿Flow构建器创建数据流文章中我们探索了flow的简单使用及它的简单原理,但是生产过程中我们往往会借用这些基础的api实现我们复杂的逻辑处理,根据需求也推出了StateFlow和SharedFlow这两个特殊的flow。接下来开始看下这几个Flow的特殊之处和应用场景吧~~

官方推荐的Flow数据流流向:

数据流程

数据流包含三个实体:

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

大致流程

  • Producer通过MVVM的Model层提供,DDU的DataLayer层提供原始数据流;
  • Intermediary通过MVVM的ViewModel层,DDU的DomainLayer层提供转换可直接用于显示的数据流的操作
  • Consumer通过MVVM的View层,DDU的UI层使用转换后的数据流进行渲染展示数据。

flow的基础使用就不介绍了,读者可以查看开头提供的两个链接查看。

切换线程

在flow内部不允许使用不同的ConretineContext进行emit提交数据,所以想要在内部切换线程可以通过flowOn操作符进行转换

StateFlow & ShareFlow

StateFlow 和 SharedFlow 是 Flow API,允许数据流以最优方式发出状态更新并向多个使用方发出值。

这两个Flow和普通的Flow不一样, Flow我们知道,只有当调用collect的时候flow传入的函数才会执行,并且每次调用collect都会重新走一遍flow函数(本质是扩展函数),调用collect的时候执行这个扩展函数;但是这两个Flow不一样他们不依赖于外部调用(可配置稍后说明),他们是热流,他们发出的数据会缓存起来当有订阅者的时候再通知订阅者

StateFlow 和 SharedFlow是发出状态更新并向多个使用方发出值并且可以通过value属性获取当前最新值。类似于观察数据,数据更新,使用方接受最新数据是不是和LiveData很像。确实像,但他比LiveData更强大~~

StateFlow
  • 线程切换:相比于LiveData更新数据的操作只能在主线程进行,但是Flow可以通过flowOn来在不同的Dispatchers(线程分发器,CoruntineContext的一种)上运行切换线程的操作更加方便
  • 数据回溯:相比于LiveData自动管理version来决定是否通知Ovserve并且只能收到最新值的方式,Flow可通过构造函数配置reply字段决定获取之前的几次数据更新
  • 生命周期处理: 对于LiveData来说,通过观察调用observe函数的时候传入LifecycleOwner内部注册生命周期回调的方式相比;Flow的观察collect函数需要在协程中调用也就是需要自动管理协程的生命周期,否则可能会出现协程开启收到数据变化更新UI发送NPE的错误,所以需要控制好调用collect的协程域Scope的生命周期,好在Android提供了几个协程作用域的api去开启: 1.viewModelScope:跟随ViewModel的生命周期变化,当ViewModel观察的组件销毁调用onClear的时候自动取消协程,生命周期过长不采取一般在对数据进行处理的时候会使用

2.lifecycleScope: 此范围内启动的协程会在 Lifecycle 被销毁时取消;也可以通过when生命周期来指定何时开启,如果 Lifecycle 未至少处于所需的最低状态,则会挂起在这些块内运行的任何协程,注意是挂起而不是销毁时的取消,意味着还是会浪费资源。

一定要注意取消这个词和挂起的区别,挂起其实还是有订阅关系的当flow发射时还是会收到走collect上游并没有取消,但是取消就是协程作用域的取消collect函数不会执行了。

但是我们可以使用repeatOnLifecycle,它当离开某个生命周期的时候进行取消,符合的时候在开启一个新协程(也即会重新执行collect函数是新的订阅者)。

Android官方的警告:倾向于使用 repeatOnLifecycle API 收集数据流,而不是在 launchWhenX API 内部进行收集。由于后面的 API 会挂起协程,而不是在 Lifecycle 处于 STOPPED 状态时取消。上游数据流会在后台保持活跃状态,并可能会发出新的项并耗用资源

  • 需要给定一个初始值。
构建StateFlow &ShareFlow

官方示例:

将普通flow转换为ShareFlow(StateFlow的一种)通过shareIn操作符 需要传入以下三个参数: (这三个参数)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class NewsRemoteDataSource(...,
    private val externalScope: CoroutineScope,
) {
    val latestNews: Flow<List<ArticleHeadline>> = flow {
        ...
    }.shareIn(
        externalScope,
        replay = 1,
        started = SharingStarted.WhileSubscribed()
    )
}
  • externalScope:用于共享数据流的 CoroutineScope。此作用域函数的生命周期应长于任何使用方,以使共享数据流在足够长的时间内保持活跃状态。(超出该作用域时flow下游逻辑取消) repeatOnLifecycle针对生命周期取消订阅流的收集(上游)collect函数(符合在开启新协程重新订阅),WhileSubscribed策略配置订阅者超时时间进行取消flow函数(下游) 搭配好这两个一个是订阅者一个是被订阅者的关系处理好业务逻辑
  • replay:要重放 (replay) 至每个新收集器的数据项数量。(发射值的时候也会存储值,可理解为配置缓冲区大小用于之后“回放”)
  • started:“启动”行为政策。 1.WhileSubscribed()当存在活跃订阅者(观察flow的协程域没有被取消)时flow函数也会活跃(执行flow函数),可配置最后一个订阅者取消订阅的超时时间进行取消flow函数运行也可以配置数据过期时间(超过一段时间将会从缓冲中移除)

2.SharingStarted.Eagerly 可立即启动提供方(flow函数立马运行),使用 SharingStarted.Lazily 可在第一个订阅者出现后开始共享数据(只有当订阅时才会运行)并且都在externalScope作用域取消时取消收集。

行为政策链接

除此之外还可定义其他SharedFlow 行为:

  • 通过 replay,您可以针对新订阅者重新发送多个之前已发出的值。
  • 通过 onBufferOverflow,您可以指定相关政策来处理缓冲区中已存满要发送的数据项的情况。默认值为 BufferOverflow.SUSPEND,这会使调用方挂起。其他选项包括 DROP_LATEST 或 DROP_OLDEST
  • 通过 subscriptionCount 属性,获取活跃状态的收集器的数量。
  • 通过 resetReplayCache 函数清空数据缓存,供您在不想回放已向数据流发送的最新信息的情况下使用。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
有小伙伴说看不懂 LiveData、Flow、Channel,跟我走
LiveData、Kotlin Flow 和 RxJava 三者都属于 可观察的数据容器类,观察者模式是它们相同的基本设计模式,那么相对于其他两者,Kotlin Flow 的优势是什么呢?
用户9995743
2022/09/26
2.8K0
有小伙伴说看不懂 LiveData、Flow、Channel,跟我走
Kotlin 学习笔记(七)—— Flow 数据流学习实践指北(三)冷流转热流以及代码实例
前一节(Kotlin 学习笔记(六)—— Flow 数据流学习实践指北(二)StateFlow 与 SharedFlow)介绍完了两种热流的构造方法以及它们的特点,那有没有方法可以将冷流转化为热流呢?当然是有的。那为什么需要将冷流转化为热流呢?
修之竹
2023/03/24
1.5K0
Kotlin 学习笔记(七)—— Flow 数据流学习实践指北(三)冷流转热流以及代码实例
Kotlin 学习笔记(六)—— Flow 数据流学习实践指北(二)StateFlow 与 SharedFlow
上节(Kotlin 学习笔记(五)—— Flow 数据流学习实践指北(一))主要讲述了 Flow 的组成、Flow 常用操作符以及冷流的具体使用。这节自然就要介绍热流了。先来温习下:
修之竹
2023/03/24
1.7K1
Kotlin 学习笔记(六)—— Flow 数据流学习实践指北(二)StateFlow 与 SharedFlow
SharedFlow vs StateFlow,一篇看懂选择和使用技巧
在Android应用开发中,数据流是一个至关重要的概念。而在Jetpack库中,SharedFlow 和 StateFlow 是两个处理数据流的利器,它们基于协程,提供了一种响应式的编程方式。本文将深入探讨这两个类的原理,以及在实际开发中的使用技巧。
Rouse
2023/12/26
2.2K0
SharedFlow vs StateFlow,一篇看懂选择和使用技巧
理解协程、LiveData 和 Flow
从 API 1 开始,处理 Activity 的生命周期 (lifecycle) 就是个老大难的问题,基本上开发者们都看过这两张生命周期流程图:
Android 开发者
2020/05/18
2.3K0
理解协程、LiveData 和 Flow
了解 Kotlin Flow(一)
最近了解了一下 Koltin Flow 相关的一些内容。在这里做一些简单的总结。关于 Flow 的知识点有如下一些:
烧麦程
2022/05/10
1.1K0
了解 Kotlin Flow(一)
Android面试题之kotlin热流和channel
StateFlow是一个状态容器式可观察数据流,可以向其收集器发出当前状态更新和新状态更新。还可通过其value属性读取当前的状态值
AntDream
2024/06/13
1440
Android面试题之kotlin热流和channel
大揭秘,Android Flow面试官最爱问的7个问题
在Android领域,面试是展示个人技能和经验的重要场合。本文将围绕Android中的Flow相关技巧展开,深入分析高级疑难问题,帮助Android技术人员提升面试水平。
Rouse
2024/01/12
3930
大揭秘,Android Flow面试官最爱问的7个问题
Flow简介
Kotlin 协程中使用挂起函数可以实现非阻塞地执行任务并将结果返回回来,但是只能返回一个计算结果。但是如果希望有多个计算结果返回回来,则可以使用 flow,flow有像Rxjava的各种操作符,实现各种功能,同时和协程一起使用,可以替代Rxjava和liveData,并且也没有像Rxjava上手这么难,所以学kotlin,flow是必须的。
HelloJack
2022/12/31
1K0
Flow简介
再谈协程之第三者Flow基础档案
该来的还是来了,LiveData提供了响应式编程的基础,搭建了一套数据观察者的使用框架,但是,它相当于RxJava这类的异步框架来说,有点略显单薄了,这也是经常被人诟病的问题,因此,Flow这个小三就顺应而生了。
用户1907613
2021/09/29
6450
Kotlin上的反应式流-SharedFlow和StateFlow
在本教程中,你将学习Kotlin中的反应式流,并使用两种类型的流——SharedFlow和StateFlow,构建一个应用程序。
用户1907613
2021/11/19
2.5K0
谁能取代Android的LiveData- StateFlow or SharedFlow?
这个系列我做了协程和Flow开发者的一系列文章的翻译,旨在了解当前协程、Flow、LiveData这样设计的原因,从设计者的角度,发现他们的问题,以及如何解决这些问题,pls enjoy it。
用户1907613
2022/01/05
1.8K0
谁能取代Android的LiveData- StateFlow or SharedFlow?
Kotlin Flow响应式编程,StateFlow和SharedFlow
其实回想一下我写这个Kotlin Flow三部曲的初衷,主要还是因为我自己想学这方面的知识。
用户1158055
2023/10/18
7890
Kotlin Flow响应式编程,StateFlow和SharedFlow
Kotlin就几行代码? 用SharedFlow写个FlowEventBus
跨页面通信是一个比较常见的场景,通常我们会选择使用EventBus,但EventBus无法感知生命周期,收到消息就会回调,所以有了LiveData之后很快就有了LiveEventBus。不过它也有缺点,比如不能切换接收线程。现在SharedFlow稳定了,那是不是也能搞一波?
程序员小顾
2021/12/23
1.1K0
Kotlin 学习笔记(五)—— Flow 数据流学习实践指北(一)
Kotlin 学习笔记艰难地来到了第五篇~ 在这一篇主要会说 Flow 的基本知识和实例。由于 Flow 内容较多,所以会分几个小节来讲解,这是第一小节,文章后面会结合一个实例介绍 Flow 在实际开发中的应用。
修之竹
2022/12/21
1.8K0
Kotlin 学习笔记(五)—— Flow 数据流学习实践指北(一)
【译】LiveData with Coroutines and Flow
这个系列我做了协程和Flow开发者的一系列文章的翻译,旨在了解当前协程、Flow、LiveData这样设计的原因,从设计者的角度,发现他们的问题,以及如何解决这些问题,pls enjoy it。
用户1907613
2021/12/01
1.5K0
【译】LiveData with Coroutines and Flow
协程 Flow 最佳实践 | 基于 Android 开发者峰会应用
本文介绍了我们在开发 2019 Android 开发者峰会 (ADS) 应用时总结整理的 Flow 最佳实践 (应用源码已开源),我们将和大家共同探讨应用中的每个层级将如何处理数据流。
Android 开发者
2020/05/18
3.7K0
协程 Flow 最佳实践 | 基于 Android 开发者峰会应用
使用更为安全的方式收集 Android UI 数据流
在 Android 应用中,通常需要从 UI 层收集 Kotlin 数据流,以便在屏幕上显示数据更新。同时,您也会希望通过收集这些数据流,来避免产生不必要的操作和资源浪费 (包括 CPU 和内存),以及防止在 View 进入后台时泄露数据。
Android 开发者
2022/03/09
1.1K0
解决Android开发中的痛点问题用Kotlin Flow
本文旨在通过实际业务场景阐述如何使用Kotlin Flow解决Android开发中的痛点问题,进而研究如何优雅地使用Flow以及纠正部分典型的使用误区。有关Flow的介绍及其操作符用法可以参考:异步流 - Kotlin 语言中文站,本文不做赘述。基于LiveData+ViewModel的MVVM架构在某些场景下(以横竖屏为典型)存在局限性,本文会顺势介绍适合Android开发的基于Flow/Channel的MVI架构。
程序员小何SS
2021/11/25
3.6K0
实战 | 使用 Kotlin Flow 构建数据流 "管道"
Flow 是一种基于流的编程模型,本文我们将向大家介绍响应式编程以及其在 Android 开发中的实践,您将了解到如何将生命周期、旋转及切换到后台等状态绑定到 Flow 中,并且测试它们是否能按照预期执行。
Android 开发者
2022/03/29
1.6K0
实战 | 使用 Kotlin Flow 构建数据流 "管道"
相关推荐
有小伙伴说看不懂 LiveData、Flow、Channel,跟我走
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验