Android Kotlin(五)数据流StateFlow和LiveData

news2024/10/5 16:26:11

Android 上的 Kotlin 数据流  

在协程中,与仅返回单个值的挂起函数相反,数据流可按顺序发出多个值。数据流以协程为基础构建,可提供多个值。从概念上来讲,数据流是可通过异步方式进行计算处理的一组数据序列。所发出值的类型必须相同。 

来源标注:Android 上的 Kotlin 数据流  |  Android Developers

书接上篇:

Android Kotlin知识汇总(二)最佳实践-CSDN博客Android Jetpack之LiveData 使用及源码_android livedata源码-CSDN博客Android Kotlin知识汇总(二)最佳实践-CSDN博客 


Kotlin中StateFlow的使用

在 Android 中,StateFlow 非常适合需要让可变状态保持可观察的类。

StateFlow 是 Flow 的实现。默认的 Flow 是冷流,而StateFlow 是热流和 LiveData 类似。

使用 StateFlow 替代 LiveData 应该是目前很多开发者的呼吁了,确实 LiveData 的功能 StateFlow 都能实现,可以说是 LiveData 的升级版。

但请注意,StateFlow 和 LiveData 的行为确实有所不同:

  • StateFlow 需要将初始状态传递给构造函数,而 LiveData 不需要。
  • 当 View 进入 STOPPED 状态时,LiveData.observe() 会自动取消注册使用方,而从 StateFlow 或任何其他数据流收集数据的操作并不会自动停止。

StateFlow的特点

  • 它始终是有值的。
  • 它的值是唯一的。
  • 它允许被多个观察者共用 (因此是共享的数据流)。
  • 它永远只会把最新的值重现给订阅者,这与活跃观察者的数量是无关的。 

StateFlow的设计

StateFlow是一种单数据更新的热流,通过emit方法更新StateFlow的数据,通过value属性可以获取当前的数据。

设计中,关键讲一下MutableStateFlow接口。它接口继承自StateFlow接口,并在此基础上定义了一个新方法compareAndSet, 即通过CAS的方式更新value。代码如下:

public interface MutableStateFlow<T> : StateFlow<T>, MutableSharedFlow<T> {
    // 当前数据
    public override var value: T
    // 如果except与value相等,则将value更新为update,并返回true
    // 如果except与value不相等,不做任何操作,直接返回false
    public fun compareAndSet(expect: T, update: T): Boolean
}

StateFlow的使用

方式一

在Activity中像类似LiveData 一样的使用 StateFlow。

class DemoViewModel @Inject constructor(val savedState: SavedStateHandle) : BaseViewModel() {
    private val _searchFlow = MutableStateFlow("")
    val searchFlow: StateFlow<String> = _searchFlow
    fun changeSearch(keyword: String) {
        _searchFlow.value = keyword
    }
}
private fun testflow() {
    mViewModel.changeSearch("key")
}
override fun startObserve() {
   lifecycleScope.launchWhenCreated {
       mViewModel.searchFlow.collect {
         LogUtils.w("value $it")
       }
   }
}

方式二

通过一个 冷流 Flow 转换为 StateFlow 。

val stateFlow = flowOf(1, 2, 3).stateIn(
      scope = lifecycleScope,
      started = Lazily,
      initialValue = 1
)
lifecycleScope.launch {
      stateFlow.collect {}
}

LiveData 与 StateFlow对比

先看看它们的代码的用法。

class DemoViewModel @Inject constructor(val savedState: SavedStateHandle) : BaseViewModel() {
    private val _searchLD = MutableLiveData<String>()
    val searchLD: LiveData<String> = _searchLD

    private val _searchFlow = MutableStateFlow("")
    val searchFlow: StateFlow<String> = _searchFlow

    fun changeSearch(keyword: String) {
        _searchFlow.value = keyword
        _searchLD.value = keyword
    }
}

 Activity中触发与接收事件:

private fun testflow() {
    mViewModel.changeSearch("key")
}
override fun startObserve() {
   mViewModel.searchLD.observe(this){
     LogUtils.w("value $it")
   }

   lifecycleScope.launchWhenCreated {
     mViewModel.searchFlow.collect {
      LogUtils.w("value $it")
     }
   }
}

可以看到,代码使用上十分类似。

LiveData的缺点

  • LiveData在某些特定的场景下会丢失数据
  • LiveData 只能在主线程不能方便地支持异步化
  • LiveData 的数据变换能力远远不如 Flow
  • LiveData 粘性问题解决需要额外扩展
  • LiveData 多数据源的合流能力远远不如 Flow
  • LiveData 默认不支持防抖,值没有变化也会通知

两者在开发中如何选择呢?

  • 团队内全部是Koltin代码开发,推荐使用Flow。因为基于Kotlin代码、基于协程。但是现在很多项目还是 Java 语言开发的。那么LiveData还是很香的。
  • LiveData的学习成本与协程、Flow 的学习成本不可同日而语,开发项目是整个团队的事情,不能说你一个人会一个人用,目前LiveData的简单学习成本是很有优势的。

注意:特定的场景慎重使用postValue。比如数据密集的场景,尽量使用setValue方法。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1523610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小迪安全42WEB攻防-通用漏洞文件包含LFIRFI伪协议

#知识点: 1、解释什么是文件包含 2、分类-本地LFI&远程RFI 3、利用-配合上传&日志&会话 4、利用-伪协议&编码&算法等 #核心知识: 1、本地包含LFI&远程包含RF1-区别 一个只能包含本地&#xff0c;一个可以远程加载 具体形成原因由代码和环境配置文件决定…

PyQt5使用

安装Pyqt5信号与槽使用可视化界面编辑UI (Pyside2)ui生成之后的使用(两种方法)1 ui转化为py文件 进行import2 动态调用UI文件 安装Pyqt5 pip install pyqt5-tools这时候我们使用纯代码实现一个简单的界面 from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButto…

练习8 Web [GYCTF2020]Blacklist

这道题其实不是堆叠注入&#xff0c;但是我在联合查询无效后&#xff0c;试了一下堆叠&#xff0c;最后一步发现被过滤的sql语句太多了&#xff0c;完全没法 查阅其他wp的过程[GYCTF2020]Blacklist 1&#xff08;详细做题过程&#xff09; 是用的handler语句&#xff0c;只能用…

基于肤色模型(YCbCr模型)的人面定位统计算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

【渗透测试】redis漏洞利用

redis安装及配置 wget http://download.redis.io/releases/redis-3.2.0.tar.gz tar xzf redis-3.2.0.tar.gz cd redis-3.2.0 make cp /root/redis-6.2.6/redis.conf /usr/local/redis/bin/ cd /usr/local/redis/bin/ vi redis.conf #修改内容如下&#xff1a; #protected-mode …

第十三届蓝桥杯(C/C++ 大学B组)

目录 试题 A: 九进制转十进制 试题 B: 顺子日期 试题 C: 刷题统计 试题 D: 修剪灌木 试题 E: X 进制减法 试题 F: 统计子矩阵 试题 G: 积木画 试题 H: 扫雷 试题 I: 李白打酒加强版 试题 J: 砍竹子 试题 A: 九进制转十进制 九进制正整数 ( 2022 )转换成十进制等于多…

【Vite+Ts】自动按需引入Element-Plus

安装插件 cnpm i -D unplugin-vue-components unplugin-auto-import unplugin-element-plus修改vite.config.ts // vite.config.ts import AutoImport from "unplugin-auto-import/vite"; import Components from "unplugin-vue-components/vite"; impor…

字符串函数和内存函数的模拟实现

目录 前言 1. 字符串操作 1.1 strncpy 1.1.1 讲解 1.1.1 模拟实现 1.2 strncat 1.2.1 讲解 1.2.2 模拟实现 2. 字符串检验 2.1 strlen 2.1.1 讲解 2.1.2 模拟实现 2.2 strstr 2.2.1 讲解 2.2.2 模拟实现 3. 字符数组操作 3.1 memcpy 3.1.1 讲解 3.1.2 模拟实…

《操作系统实践-基于Linux应用与内核编程》第10章--实验 Qt聊天程序

前言: 内容参考《操作系统实践-基于Linux应用与内核编程》一书的示例代码和教材内容&#xff0c;所做的读书笔记。本文记录再这里按照书中示例做一遍代码编程实践加深对操作系统的理解。 引用: 《操作系统实践-基于Linux应用与内核编程》 作者&#xff1a;房胜、李旭健、黄…

15届蓝桥杯第三期模拟赛所有题目解析

文章目录 &#x1f9e1;&#x1f9e1;t1_奇数次数&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t2_台阶方案&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t3_约数个数&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t4_最…

特殊文本文件、日志技术

特殊文件 为什么要用这些特殊文件&#xff1f; 存储多个用户的&#xff1a;用户名、密码 特殊文件:Properties属性文件 特点&#xff1a; 都只能是键值对键不能重复文件后缀一般是.properties结尾的 作用&#xff1a;存储一些有关系的键值对数据 Properties 是一个Map集合(键…

Ubuntu Argoverse API安装

1. 创建并进入conda环境 conda create -n Argoverse python3.8 conda activate Argoverse2. 拉取argoverse-api源码 git clone https://github.com/argoai/argoverse-api.git3. 下载高精地图 Download hd_maps.tar.gz from Argoverse 4. 安装api cd argoverse-api pip in…

STM32 Simulink 自动代码生成电机控制——霍尔有感六步方波仿真到开发板运行

目录 前言 方波控制理论 仿真 代码集成到开发板运行 总结 前言 回想以前在学校手写代码实现方波控制&#xff0c;花了不少时间。现在各大MCU厂家都有自己的有感或者无感方波控制的方案。这次尝试用Simulink来完成应用层算法的仿真再到代码生成开发板运行的完整流程。 方波…

达梦数据库管理

一、表空间管理介绍 在 DM 数据库中&#xff0c;表空间由一个或者多个数据文件组成。 DM 数据库中的所有对象在逻辑上都存放在表空间中&#xff0c;而物理上都存储在所属表空间的数据文件中。 DM数据库中的表空间可以分为普通表空间和混合表空间。普通表空间不能存储HUGE表&…

《IEEE Transactions on Robotics》发表!北京大学研究团队推出具有多种运动模态的软体两栖机器人

两栖机器人以其在复杂水陆混合环境中的卓越适应性而脱颖而出&#xff0c;成为非结构化场景下信息监测、资源勘探和灾难救援等多元化任务的理想选择。凭借能够在水生和陆生环境中自如切换的优势&#xff0c;两栖机器人在如上任务执行过程中展现出对多变环境的惊人适应能力。 在…

【Godot4.2】颜色完全使用手册

概述 本篇简单汇总Godot中的颜色的构造和使用&#xff0c;内容包括了&#xff1a; RGB、RGBA&#xff0c;HSV以及HTML16进制颜色值、颜色常量等形式构造颜色颜色的运算以及取反、插值用类型化数组、紧缩数组或PNG图片形式存储多个颜色 构造颜色 因为颜色是一种视觉元素&…

配置Web运行环境与第一个网页

安装与配置Web环境: 如下使用了VSC作为web的运行环境。 下面是VSC的官网:Download Visual Studio Code - Mac, Linux, Windowshttps://code.visualstudio.com/download 进入官网后按照自己的系统下载&#xff0c;我下载的是Windows. 下载完之后双击打开。 接下来就是安装&…

探讨TCP的可靠性以及三次握手的奥秘

&#x1f31f; 欢迎来到 我的博客&#xff01; &#x1f308; &#x1f4a1; 探索未知, 分享知识 !&#x1f4ab; 本文目录 1. TCP的可靠性机制1.2可靠性的基础上,尽可能得提高效率 2. TCP三次握手过程3. 为何不是四次握手&#xff1f; 在互联网的复杂世界中&#xff0c;TCP&am…

Autosar Crypto Driver学习笔记(二)

文章目录 Crypto DriverFunction definitionsGeneral APICrypto_InitCrypto_GetVersionInfo Job Processing InterfaceCrypto_ProcessJob Job Cancellation InterfaceKey Management InterfaceKey Setting Interface密钥设置接口Crypto_KeyElementSetCrypto_KeySetValid Key Ex…

Linux操作系统及进程(一)

一、操作系统的概念 概念 &#xff1a;任何计算机系统都包含一个基本的程序集合&#xff0c;称为操作系统(OS)。笼统的理解&#xff0c;操作系统包括&#xff1a; 内核&#xff08;进程管理&#xff0c;内存管理&#xff0c;文件管理&#xff0c;驱动管理&#xff09; 其他程…