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

Android MVVM+coroutine+retrofit+flow+hilt

文章目录

  • Android MVVM+coroutine+retrofit+flow+hilt
    • 概述
    • 依赖注入层
    • 数据层
    • 视图层
    • 模型视图层
    • 代码下载

Android MVVM+coroutine+retrofit+flow+hilt

概述

在这里插入图片描述

代码结构:

在这里插入图片描述

依赖注入层

数据库:

@Module
@InstallIn(SingletonComponent::class)
class DBModule {@Singleton@Providesfun provideDB(application: Application): AppDatabase {return AppDatabase.getDatabase(application)}@Singleton@Providesfun provideCacheDao(db: AppDatabase): CacheDao {return db.cacheDao()}
}

网络请求:

@Module
@InstallIn(SingletonComponent::class)
class NetworkModule {@Singleton@Providesfun provideOkHttpClient(): OkHttpClient {return HttpManager.okHttpClient}@Singleton@Providesfun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {return HttpManager.retrofit}@Singleton@Providesfun provideLoginApi(retrofit: Retrofit): LoginApi {return retrofit.create(LoginApi::class.java)}@Singleton@Providesfun provideArticleApi(retrofit: Retrofit): ArticleApi {return retrofit.create(ArticleApi::class.java)}
}

数据层

open class BaseModel {@Injectlateinit var cacheHelper: CacheHelperfun <T> requestForResult(block: suspend () -> BaseResponse<T>): Flow<ResultState<T>> {return flow<ResultState<T>> {val response = block()if (response.isSuccessful()) {emit(ResultState.Success(response.data!!))} else {val serverException = ServerException(response.errorCode, response.errorMsg)val e = ExceptionHandler.handleException(serverException)emit(ResultState.Error(e, e.displayMessage))}}.flowOn(Dispatchers.IO).catch {val e = ExceptionHandler.handleException(it)emit(ResultState.Error(e, e.displayMessage))}}suspend fun <T> requestForResult(cacheName: String,cacheBlock: () -> T?,block: suspend () -> BaseResponse<T>): Flow<ResultState<T>> {return flow {val cacheData = cacheBlock()cacheData?.let {emit(ResultState.Success(cacheData, true))}val response = block()if (response.isSuccessful()) {cacheHelper.saveCache(cacheName, response.data!!)emit(ResultState.Success(response.data, false))} else {val serverException = ServerException(response.errorCode, response.errorMsg)val e = ExceptionHandler.handleException(serverException)emit(ResultState.Error(e, e.displayMessage))}}.flowOn(Dispatchers.IO).catch {val e = ExceptionHandler.handleException(it)emit(ResultState.Error(e, e.displayMessage))}}
}
class ArticleModel @Inject constructor() : BaseModel() {@Injectlateinit var articleApi: ArticleApisuspend fun getArticleList(): Flow<ResultState<ArrayList<ArticleBean>>> {val cacheName = "article_list"return requestForResult(cacheName, {cacheHelper.getCache<ArrayList<ArticleBean>>(cacheName, object : TypeToken<ArrayList<ArticleBean>>() {}.type)}, {articleApi.getArticleList()})}
}

视图层

abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {private lateinit var _mViewBinding: VBprotected val mViewBinding get() = _mViewBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)_mViewBinding = createViewBinding()setContentView(_mViewBinding.root)initViews()initData(savedInstanceState)}abstract fun createViewBinding(): VBabstract fun initViews()abstract fun initData(savedInstanceState: Bundle?)
}

@AndroidEntryPoint
class ArticleListActivity : BaseActivity<ActivityArticleListBinding>() {private val mList = arrayListOf<ArticleBean>()private val articleListViewModel by viewModels<ArticleViewModel>()private val progressDialog: ProgressDialog by lazy {ProgressDialog(this).apply {setMessage("加载中")}}override fun createViewBinding(): ActivityArticleListBinding {return ActivityArticleListBinding.inflate(layoutInflater)}override fun initViews() {}override fun initData(savedInstanceState: Bundle?) {mViewBinding.rvArticleList.adapter = ArticleAdapter(this, mList)mViewBinding.btnGetArticleList.setOnClickListener {getArticleList()}observe()}private fun getArticleList() {articleListViewModel.getArticleList()}private fun observe() {lifecycleScope.launch {repeatOnLifecycle(Lifecycle.State.RESUMED) {articleListViewModel.articleFlow.collect {when (it) {is ResultState.Loading -> showLoading()is ResultState.Error -> {showToast(it.message)hideLoading()}is ResultState.Success -> {hideLoading()updateUI(it.data)}}}}}}private fun updateUI(list: ArrayList<ArticleBean>?) {mList.clear()if (list != null) {mList.addAll(list)}mViewBinding.rvArticleList.adapter!!.notifyDataSetChanged()}private fun showLoading() {progressDialog.show()}private fun hideLoading() {progressDialog.hide()}
}

模型视图层

open class BaseViewModel : ViewModel() {fun launchMain(block: suspend CoroutineScope.() -> Unit) {viewModelScope.launch(Dispatchers.Main) {block()}}fun launchIO(block: suspend CoroutineScope.() -> Unit) {viewModelScope.launch(Dispatchers.IO) {block()}}fun launchDefault(block: suspend CoroutineScope.() -> Unit) {viewModelScope.launch(Dispatchers.Default) {block()}}
}
@HiltViewModel
class ArticleViewModel @Inject constructor(private val articleModel: ArticleModel
) : BaseViewModel() {private val _articleFlow =MutableStateFlow<ResultState<ArrayList<ArticleBean>>>(ResultState.None)val articleFlow get() = _articleFlow.asStateFlow()fun getArticleList() {launchIO {articleModel.getArticleList().onStart {_articleFlow.value = ResultState.Loading}.collect {_articleFlow.value = it}}}
}

代码下载

相关文章:

Android MVVM+coroutine+retrofit+flow+hilt

文章目录 Android MVVMcoroutineretrofitflowhilt概述依赖注入层数据层视图层模型视图层代码下载 Android MVVMcoroutineretrofitflowhilt 概述 代码结构&#xff1a; 依赖注入层 数据库&#xff1a; Module InstallIn(SingletonComponent::class) class DBModule {Singleto…...

elasticsearch副本和分片

1.文档冲突 当我们使用index API更新文档&#xff0c;可以一次性读取 修改索引副本 rootes-node3:~# curl -XPUT http://192.168.1.136:9200/es-syslog-2023.08.26/_settings -H "Content-Type: application/json" -d { > "settings": { > …...

【Python】zip

Python中的zip()函数可以将多个可迭代对象打包成一个元组序列&#xff0c;然后返回这些元组序列组成的迭代器。zip()函数的语法如下&#xff1a; zip(*iterables)其中&#xff0c;iterables是可迭代对象&#xff0c;可以是多个&#xff0c;也可以是一个。zip()函数将返回一个迭…...

西安安泰——ATA-1220E宽带放大器

ATA-1220E宽带放大器简介 ATA-1220E是一款可放大交直流信号的差分通道宽带放大器。其最大输出电压 60Vp-p(30Vp)&#xff0c;最大输出电流1Ap&#xff08;>50Hz&#xff09;。电压增益数控可调&#xff0c;一键保存设置&#xff0c;提供了方便简洁的操作选择&#xff0c;可…...

数据结构和算法专题---4、限流算法与应用

本章我们会对限流算法做个简单介绍&#xff0c;包括常用的限流算法&#xff08;计数器、漏桶算法、令牌桶案发、滑动窗口&#xff09;的概述、实现方式、典型场景做个说明。 什么是限流算法 限流是对系统的一种保护措施。即限制流量请求的频率&#xff08;每秒处理多少个请求…...

亚信安慧AntDB受邀分享核心业务系统全域数据库替换实践

近日&#xff0c;亚信安慧AntDB数据库凭借丰富的核心业务系统升级替换能力和经验&#xff0c;受邀参与IT168组织的第三期“国产软硬件升级替换之路”的直播沙龙。 亚信安慧AntDB数据库相关负责人发表《基于AntDB的CRM全域数据库替换实践》的精彩演讲&#xff0c;通过通信行业率…...

1.uniapp基础

1.uniapp基础 官方文档&#xff1a;uni-app官网 1.1开发工具 &#xff08;1&#xff09;工具&#xff1a; HBuilderX HBuilderX-高效极客技巧 1.2 新建项目 &#xff08;1&#xff09; 文件》新建项目 ​ &#xff08;2&#xff09;选择相应的配置信息&#xff0c;填写项目根路…...

typescript中的策略模式

typescript中的策略模式 当我们需要以整洁、易于维护和易于调试的方式构建应用程序时&#xff0c;使用设计模式是一种非常好的方式。 在本文中&#xff0c;我们的目标是阐明如何将策略模式无缝地集成到我们的应用程序中。如果我们熟悉依赖性注入&#xff0c;可能会发现策略模…...

Hadoop学习笔记(HDP)-Part.16 安装HBase

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …...

C语言练习记录(蓝桥杯练习)(小蓝数点)

目录 小蓝数点 第一题程序的输出结果是&#xff1f;: 第二题下面代码的执行结果是什么&#xff1f;: 第三题下面代码的执行结果是什么&#xff1f;: 第四题关于关系操作符说法错误的是&#xff1f;: 第五题对于下面代码段&#xff0c;y的值为&#xff1f; 第六题sum 21 …...

RPG项目01_层级设置

基于“RPG项目01_UI面板Game”&#xff0c; 找到狼人 添加组件&#xff0c;让狼人一定区域自动跟随主角进行攻击 解释&#xff1a;【烘培蓝色】因为如果什么都不做就会被烘培成蓝色对应的功能就是 可修改区域功能 当将区域设置成不可行走状态&#xff0c;则不为蓝色 烘培&…...

相关基础知识

本文引注&#xff1a; https://zhuanlan.zhihu.com/p/447221519 1.方差 2.自协方差矩阵 3.自相关矩阵 4.互协方差矩阵 5.互相关矩阵 6.相关系数 7.自相关函数、自协方差函数与功率谱密度 8.互相关函数、互协方差函数与互功率谱密度...

基于单片机的智能健康监测手环的设计

目 录 1 绪论... 2 1.1 引言... 2 1.2 智能手环的国内外研究现状... 2 1.3 课题的研究意义... 3 1.4 本文的研究内容和章节安排... 4 2 智能手环系统设计方案... 5 2.1 系统总体设计方案... 5 2.2 主芯片选择... 5 2.3 显示方案的选择... 6 2.4 倾角传感器的选择... 6 2.5 心率…...

boost-字符串处理-判断-查找-裁剪-删除-替换-分割-合并

文章目录 1.判断1.1.equals1.2.all1.3.starts_with1.4.ends_with1.5.contains 2.大小写转换3.字符串删除4.字符串替换5.字符串查找6.字符串修剪7.字符串分割8.字符串合并9.总结 1.判断 判别式函数和分类函数大多数都是以is_开头&#xff0c;这些函数如下&#xff1a; 判别式函…...

Django 开发 web 后端,好用过 SpringBoot ?

基础语法 Django&#xff08;Python&#xff09;&#xff1a;以简洁和直观著称。它允许更快的开发速度&#xff0c;特别适合快速迭代的项目。例如&#xff0c;一个简单的视图函数&#xff1a; from django.http import HttpResponsedef hello_world(request):return HttpRespon…...

【矩阵】54.螺旋矩阵(顺时针打印矩形元素)

题目 class Solution {public List<Integer> spiralOrder(int[][] matrix) {int m matrix.length, n matrix[0].length;int leftUpM 0, leftUpN 0, rightDownM m - 1, rightDownN n - 1;List<Integer> res new ArrayList<>();while (leftUpM < ri…...

【数据中台】开源项目(5)-Amoro

介绍 Amoro is a Lakehouse management system built on open data lake formats. Working with compute engines including Flink, Spark, and Trino, Amoro brings pluggable and self-managed features for Lakehouse to provide out-of-the-box data warehouse experience,…...

_WorldSpaceLightPos0的含义 UNITY SHADER

_WorldSpaceLightPos0 为当前平行光的方向&#xff0c;方向是从光源到照射的方向。 因此&#xff0c;如果要算法线和平行光之间的夹角&#xff0c; 则需要首先将归一化的_WorldSpaceLightPos0去负数。这样才能继续去计算。 也就是&#xff1a; fixed3 reflectdirnormalize…...

iOS不越狱自动挂机

自动挂机在电脑上或者安卓手机上都相对容易&#xff0c;而在不越狱的iOS设备上还是有点难度的。 此方法不是我原创&#xff0c;详情见&#xff1a; 【苹果党福音&#xff0c;ios也能用的挂机脚本】 https://www.bilibili.com/video/BV1sv4y1P7TL/?share_sourcecopy_web&v…...

智能优化算法应用:基于鼠群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于鼠群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于鼠群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鼠群算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...