Android数据缓存框架 - 内存数据载体从LiveData到StateFlow

引言:所有成功者的背后,都有一份艰苦的历程,不要只看到了人前的风光,而低估了他们背后所付出的努力。

随着flow到流行度越来越高,有开发者呼吁我使用flow,于是我就如你们所愿,新增了StateFlow作为新的数据载体。当然你仍然可以使用旧版本的LiveData,代码写法略微不同罢了。如果对我的dcache框架设计不是很理解的小伙伴,可以看我的专栏其他文章。

为什么推荐使用StateFlow

如果你非要问我为什么要使用StateFlow?我可以告诉你,因为可以装逼,哈哈,开个玩笑。新技术的流行必然有一部分炒作的部分,但也肯定是有其改进的地方的。要讲StateFlow,就不得不从flow开始说起。flow是属于kotlin语言范畴的,你可以把它当成kotlin协程的一个API。没错,kotlin语言的野心就是要做跨平台的语言,答案就在这里,LiveData是android的API,而SharedFlow与StateFlow直接就是Kotlin编程语言级别的,代码复用性更好。

LiveData和StateFlow使用对比

以列表数据模式的Repository为例。从2.1.5开始@Repository注解拆分成了@Repository注解和@ListRepository,所以2.1.4版本你应该使用@Repository注解,而如果说,你使用的是2.1.5及以上版本的dcache库,要使用@ListRepository注解。由于StateFlow在2.2.0版本才开始支持,所以自然要使用@ListRepository注解。
先看StateFlow的写法。

override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 此处省略代码若干行lifecycleScope.launchWhenCreated {repository.getListFlowData().collect {adapter.setTemperatures(it)}}
}

不要忘了使用协程作用域。
然后我们调用fetchListData()。

repository.fetchListData(listener = object : OnLoadStateListener {override fun onLoad(state: Int) {Log.d("WeatherActivity", "数据是否加载成功:${state==0}")}
}, description = null)

加载状态监听接口和描述信息可以传null。这个抓取数据方法一经调用,collect代码块就会刷新数据。由于fetchListData()天然就返回的StateFlow,所以你并不一定要分为两步观察数据。而如果你要分为两步,则调用getListFlowData()或getFlowData()。
再看原来LiveData的写法,这次我们不用list模式的Repository,如果要使用,直接配置@Repository注解。

minutelyRepository.latlng = "116.407526,39.90403"
minutelyRepository.fetchData("按分钟统计天气").observe(this, Observer {it?.apply {tvCacheMinutely.text = "minutely:${toString()}\n"}
})

很明显,fetchData()返回LiveData,直接调用observe()进行数据的观察。简单总结下,API的设计在调用层面具有相似性,所以,无论你使用的是LiveData为数据载体的Repository还是StateFlow的,都是调用fetchData()或fetchListData()更新缓存数据,框架内部自动帮你缓存到数据库,同时常驻在内存并递送给UI层刷新界面。所以你可以专心开发你的业务逻辑,这是不是很棒?

package com.example.dcache.repositoryimport android.content.Context
import com.example.dcache.biz.weather.WeatherService
import com.example.dcache.model.WeatherModel
import dora.cache.data.fetcher.OnLoadStateListener
import dora.cache.repository.DoraDatabaseCacheRepository
import dora.cache.repository.Repository
import dora.http.DoraCallback
import dora.http.retrofit.RetrofitManager@Repository
class WeatherRepository(context: Context) : DoraDatabaseCacheRepository<WeatherModel>(context) {var latlng: String = ""override fun onLoadFromNetwork(callback: DoraCallback<WeatherModel>,listener: OnLoadStateListener?) {RetrofitManager.getService(WeatherService::class.java).getWeather(latlng).enqueue(callback)}
}

最后简单复习一下Repository的写法。详细Demo代码https://github.com/dora4/DoraCacheSample 。

框架设计的变化

这是StateFlow的。

/*** 用于网络数据抓取。*/
interface IFlowDataFetcher<M> {/*** 清空flow data的数据。*/fun clearData()/*** 抓取数据的回调。*/fun callback(): DoraCallback<M>/*** 开始抓取数据。*/fun fetchData(description: String?, listener: OnLoadStateListener? = OnLoadStateListenerImpl()): StateFlow<M?>/*** 获取flow data。*/fun getFlowData(): StateFlow<M?>
}

这是LiveData的。

package dora.cache.data.fetcherimport androidx.lifecycle.LiveData
import dora.http.DoraCallback/*** 用于网络数据抓取。*/
interface IDataFetcher<M> {/*** 清空livedata的数据。*/fun clearData()/*** 抓取数据的回调。*/fun callback(): DoraCallback<M>/*** 开始抓取数据。*/fun fetchData(description: String?, listener: OnLoadStateListener? = OnLoadStateListenerImpl()): LiveData<M?>/*** 获取livedata。*/fun getLiveData(): LiveData<M?>
}

是不是没啥变化?对的,这就是架构设计的魅力所在。前期架构设计比较到位,所以只需要遵循开闭原则。对扩展开放,对修改关闭。
截屏2024-01-07 17.31.22.png
原先继承BaseRepository的,现在继承BaseFlowRepository的。名字有带Flow单词的,就是StateFlow的。

开源框架支持

笔者写框架和文档不容易,希望你的支持。你的支持是我改进优化最大的动力!

数据缓存dcache框架 https://github.com/dora4/dcache-android

dora框架的开发插件 https://github.com/dora4/dora-studio-plugin

dora框架 https://github.com/dora4/dora

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

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

相关文章

智能时代下,人机交互和虚拟现实的机遇和挑战

智能时代下,人机交互和虚拟现实的机遇和挑战

多态(C++)

多态(C) 本文如果有错误或者不足的地方&#xff0c;希望各位大佬多多指点。 【本文目录】 1.多态的概念2.多态的定义及实现3.抽象类4.多态的原理5.单继承和多继承的虚函数表 1.多态的概念 多态的概念就是&#xff1a;多种形态 多态就是可以有多种的形态。不同的身份去实现同一…

【Leetcode 160】环形链表——双指针,细节讲解

题目 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#…

RTSP/Onvif安防视频监控云平台EasyNVR重启后通道在线视频无法播放,接口报错502是什么原因?

EasyNVR安防视频云平台是旭帆科技TSINGSEE青犀旗下支持RTSP/Onvif协议接入的安防监控流媒体视频云平台。平台具备视频实时监控直播、云端录像、云存储、录像检索与回看、告警等视频能力&#xff0c;能对接入的视频流进行处理与多端分发&#xff0c;包括RTSP、RTMP、HTTP-FLV、W…

hypack如何采集多波束数据?(下)

多波束测量模块 1&#xff09;记录多波束和辅助传感器的数据&#xff1b; 2&#xff09;显示实时改正后的数据和数据质量信息。 ​编辑​ 测量准备 1&#xff09;设置大地测量参数和硬件设置&#xff1b; 2&#xff09;计划测线 计划测线是一定间距的平行线&#xff0c;…

微软联手清华,AI注释让文本到图像生成更符合人类偏好

获取本文论文原文PDF&#xff0c;请在公众号【AI论文解读】留言&#xff1a;论文解读 摘要 本研究展示了利用人类偏好数据集来精细调整文本到图像生成模型的潜力&#xff0c;增强了生成图像与文本提示之间的一致性。尽管取得了进展&#xff0c;现有的人类偏好数据集要么构建成…

掌控安全CTF-2024年5月擂台赛-WP(部分)

MISC ez_Misc 题目给了一个加密的压缩包和一个文本文档&#xff0c;首先我们先来看文本的内容&#xff0c;如下&#xff1a; 很容易看出&#xff0c;0宽隐写&#xff0c;用PuzzleSolver梭哈一下&#xff0c;发现了&#xff1a;Thi3 is n0t 2 hint 又在文本中发现一个特征&…

【2024】高校网络安全管理运维赛

比赛时间&#xff1a;2024-05-06 Re-easyre 基本的base64换表&#xff0c;用CyberChef解密 Re-babyre 进入主函数&#xff0c;发现输入四次 看一下就知道是大数求解 (当初写的时候差不多 不知道为什么第四个总是算错…) from z3 import *s Solver() # 设置一个解方程的类…

中心渗透Ⅱ

cs与msf权限传递以及mimikatz抓取win2012明文密码 使用Cobalt Strike抓取win2012明文密码&#xff0c;将会话传递到Metasploit Framework上 1.cs生成木马并使目标服务器中马 建立监听生成木马 2.抓取目标主机的明文密码 通过修改注册表来让Wdigest Auth保存明文口令 shell …

深入pandas:数据分析

目录 前言 第一点&#xff1a;导入模块 第二点&#xff1a;准备数据 第三点&#xff1a;简单的分析数据 第四点&#xff1a;【重点】数据透支 总结 前言 在数据分析与挖掘的领域&#xff0c;了解如何使用工具和方法来探索数据是至关重要的。本文将探讨如何利用Python中的…

C语言常用字符串处理函数

C语言中包含了很多对字符串处理的函数,要使用这些函数&#xff0c; 首先需要导入头文件#include <string.h> 1. strlen() -- 计算字符串长度 原型: size_t strlen(char const *string); 例: char *str "abcde"; size_t len strlen(str); // 结果为…

【DevOps】Elasticsearch在Ubuntu 20.04上的安装与配置:详细指南

目录 一、ES 简介 1、核心概念 2、工作原理 3、 优势 二、ES 在 Ubuntu 20.04 上的安装 1、安装 Java 2、下载 ES 安装包 3、创建 ES 用户 4 、解压安装包 5、 配置 ES 6、 启动 ES 7、验证安装 三、ES 常用命令 1、创建索引 2、 插入文档 3、查询文档 四、ES…

利用audacity和ffmpeg制作测试音频文件

最近要用SIPP测试一个场景&#xff0c;需要发送双声道/16K采样率/16bit量化的PCM流&#xff0c;但是下载的素材往往不能满足参数要求。那么就自己制作。 首先下载mp3文件&#xff0c;并用audacity打开。 接下来&#xff0c;点击菜单栏中轨道-重采样&#xff0c;将采样频率设为1…

【Java面试】四、MySQL篇(上)

文章目录 1、定位慢查询2、慢查询的原因分析3、索引3.1 数据结构选用&#xff1a;二叉树 & 红黑树3.2 数据结构选用&#xff1a;B树 4、聚簇索引、非聚簇索引、回表查询4.1 聚簇索引、非聚簇索引4.2 回表查询 5、覆盖索引、超大分页优化5.1 覆盖索引5.2 超大分页处理 6、索…

联发科MT8370平台Genio 510物联网应用程序处理器详细规格参数

MT8370是一款高度集成、功能强大的平台&#xff0c;专为各种人工智能(AI)和物联网(IoT)用例而设计&#xff0c;这些用例需要高性能边缘处理、先进的多媒体和连接功能、多个高分辨率摄像头、连接的触摸屏显示器以及多任务高级操作系统(HLOS)的使用。http://Genio 510 (MT8370) E…

Mybatis源码剖析

文章目录 一、前置1.1概念ORMSqlSession会话 二、快速入门2.1 SpringBoot整合Mybatis2.2 XML配置2.2.1 路径位置2.2.2 名称2.2.3 configuration标签内容环境environments标签映射器mappers标签 2.3 Mapper接口2.3.1 单Mybatis项目2.3.2 SpringBoot整合mybatis2.3.3 m整合mybati…

字符串函数(2)<C语言>

前言 快一周没更博客了&#xff0c;最近有点忙&#xff0c;今天闲下来了&#xff0c;还是不行&#xff0c;继续干&#xff0c;书接上回继续介绍字符串函数&#xff1a;strncpy()、strncat()、strcmp()、strtok()使用、strstr()使用以及模拟实现、strerror()使用。 strncpy()、s…

揭秘网络编程:同步与异步IO模型的实战演练

摘要 ​ 在网络编程领域&#xff0c;同步(Synchronous)、异步(Asynchronous)、阻塞(Blocking)与非阻塞(Non-blocking)IO模型是核心概念。尽管这些概念在多篇文章中被广泛讨论&#xff0c;它们的抽象性使得彻底理解并非易事。本文旨在通过具体的实验案例&#xff0c;将这些抽象…

在React中使用Sass实现Css样式管理-10

0. 什么是Sass Sass(Syntactically Awesome Stylesheets)是一个 CSS 预处理器&#xff0c;是 CSS 扩展语言&#xff0c;可以帮助我们减少 CSS 重复的代码&#xff0c;节省开发时间&#xff1a; Sass 引入合理的样式复用机制&#xff0c;可以节约很多时间来重复。支持变量和函…

C++之“流”-第2课-C++和C标准输入输出同步

为什么C和C的标准输入输出不同步时&#xff0c;数据会混乱&#xff1f;同步会带来多大性能损失&#xff1f;为什么说这个损失通常不用太在乎&#xff1f; 0. 课堂视频 C之“流”-第2课&#xff1a;和C输入输出的同步 1. 理解cin和cout的类型与创建过程 std::cout 是std::ostre…