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}}}
}

代码下载

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

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

相关文章

数据结构与算法-D2D3线性表之顺序表

线性表&#xff1a;包含若干数据元素的一个线性序列&#xff0c;特征如下&#xff1a; 1&#xff09;对非空表&#xff0c;a0是表头&#xff0c;无前驱&#xff1b; 2&#xff09;an-1是表尾&#xff0c;无后继&#xff1b; 3&#xff09;其他元素仅且仅有一个前驱&#xff0c;…

基于YOLOv8深度学习的120种犬类检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战、狗类检测、犬种识别

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

【“C++ 精妙之道:解锁模板奇谭与STL精粹之门“】

【本节目标】 1. 泛型编程 2. 函数模板 3. 类模板 4. 什么是STL 5. STL的版本 6. STL的六大组件 7. STL的重要性 8. 如何学习STL 9.STL的缺陷 1. 泛型编程 如何实现一个通用的交换函数呢&#xff1f; void Swap(int& left, int& right) {int temp left;lef…

odoo自定义提示性校验

背景: 在odoo16的原生的代码里&#xff0c;可以给按钮添加一个 confirm属性&#xff0c;从而达到 提示性校验的效果。 问题&#xff1a; 这个属性加了之后一定会弹出提示性校验的对话框&#xff0c;于是如何根据我们的实际业务&#xff0c;从后端返回提示性信息&#xff0c;…

5.2k Star!一个可视化全球实时天气开源项目!

大家好&#xff0c;本文给大家推荐一款全球实时天气开源项目&#xff1a;Earth。 项目简介 Earth 是一个可视化全球天气实况的项目。该项目以可视化的方式展示了全球的天气情况&#xff0c;提供了风、温度、相对湿度等多种天气数据&#xff0c;以及风、洋流和波浪的动画效果…

2-1、地址加法器CS:IP

语雀原文链接 文章目录 1、CPU组成2、通用寄存器16位寄存器的存储16位寄存器兼容8位word 和 byte进位问题 3、地址加法器不同的段地址和偏移地址表示同一个物理地址偏移地址的范围一个段的起始地址一定是16的倍数 4、CS:IPCS IP工作过程jmp修改CS:IP 5、DS和[address]DS和[add…

蓝桥杯算法心得——仙界诅咒(dfs)

大家好&#xff0c;我是晴天学长&#xff0c;搜索型的dfs&#xff0c;差点开二维矩阵了&#xff0c;仔细一想&#xff0c;没那么夸张啊&#xff0c;哈哈哈&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1…

性能工具之JMeter二次开发总结

文章目录 一、前言二、自定义脚本三、自定义请求编写&#xff08;Java Sampler&#xff09;四、自定义函数五、小结 一、前言 掌握 JMeter 的脚本编写和执行&#xff0c;这基本已满足大部分的性能测试需求&#xff0c;但是面对各种各样的项目技术方案&#xff0c;有些需求是需…

mybatis多表查询(xml)

多表查询都用resultMap resultMap 说白了就是他可以手动设置映射参数&#xff0c;例如 可以指定 column代表数据库的参数 property 代表实体类的参数 <id column"roleid" property"id"></id> column代表数据库的参数 property 代表实体类…

【隐私计算】安全三方计算(3PC)的加法和乘法计算协议

ABY3中采用replicated secret sharing&#xff08;复制秘密分享&#xff09;机制&#xff0c;即2-out-of-3秘密分享&#xff0c;三个参与方的每一方都拥有share中的两份。下面来看一下这样做有什么好处。 2-out-of-3秘密分享 有 x , y x, y x,y两个操作数&#xff0c;先进行秘…

列表插槽使用

{label: 是否展示,prop: isShow,solt: true, }<!--自定义列 展示 1 不展示 0 --><template slot-scope"scope" slot"display"><div style"color: red;cursor: pointer"><el-switch v-model"scope.row.display" :…

在gitlab中使用gitlab-sshd替换ssh服务

参考&#xff1a;https://docs.gitlab.com/ee/administration/operations/gitlab_sshd.html 说明 gitlab-sshd 是 OpenSSH 的轻量级替代品&#xff0c;用于提供 SSH 操作。虽然 OpenSSH 使用受限的 shell 方法&#xff0c;但 gitlab-sshd 的行为更像是一个现代的多线程服务器应…

ssm的网上奶茶店系统(有报告)。Javaee项目。

演示视频&#xff1a; ssm的网上奶茶店系统&#xff08;有报告&#xff09;。Javaee项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring SpringMvc Mybat…

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

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

全面解析修复msvcr120.dll缺失问题的方法,msvcr120.dll丢失的原因

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中最常见的就是“msvcr120.dll丢失”。这个错误通常会导致某些程序无法正常运行&#xff0c;给用户带来很大的困扰。那么&#xff0c;当我们遇到这个问题时&#xff0c;应该如何修复呢&#xff1f;本文…

【6】PyQt信号和槽

1. 信号和槽简介 信号和槽机制是 QT 的核心机制&#xff0c;应用于对象之间的通信 信号和槽是用来在对象间传递数据的方法当一个特定事件发生的时候&#xff0c;signal会被emit出来&#xff0c;slot调用是用来响应相应的signal的Qt中对象已经包含了许多预定义的 signal&#…

JAVA 线程池,及7大参数,4大拒绝策略详解

为什么要使用线程池 线程的生命周期&#xff1a;运行、就绪、运行、阻塞、死亡 下面是一个简单的创建多线程的方法。注意&#xff1a;工作中不可取。 创建线程的时候&#xff0c;我们避不开线程的生命周期。上面的方法虽然可以创建多线程&#xff0c;但是创建完成后&#xff0c…

Ubuntu 环境安装 Kafka、配置运行测试 Kafka 流程笔记

Kafka 介绍 Kafka 是一个由 Apache 软件基金会开发的开源流式处理平台。它被设计用于处理大规模数据流&#xff0c;提供高可靠性、高吞吐量和低延迟的消息传递系统。Kafka 可以用于构建实时数据管道和流式应用程序&#xff0c;让不同应用、系统或者数据源之间能够高效地进行数…

老师怎样避免精神内耗?

在老师的职业生涯中&#xff0c;遇到的挑战和压力可能会导致精神内耗&#xff0c;这会影响到心理和身体健康&#xff0c;更进一步影响到工作成果和个人生活。为了避免精神内耗&#xff0c;老师可以尝试以下方法&#xff1a; 1. 建立正面的心态&#xff1a;老师需要学会积极思考…

卡码网语言基础课 | 19. 洗盘子

目录 一、 栈的基本概念 二、 栈的操作 2.1 引入头文件 2.2 创建栈 2.3 栈的基本认识 三、 解答 通过本次练习&#xff0c;将学习到以下 C知识点&#xff1a; 栈的基本概念&#xff08;空栈、栈顶、栈底&#xff09;和特点&#xff08;先入后出&#xff09;入栈、出栈、获取…