当前位置: 首页 > 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}}}
}

代码下载

相关文章:

  • STM32(PWM、ADC)
  • JS箭头函数
  • maven-profile
  • 在AWS Lambda上部署EC2编译的FFmpeg工具——自定义层的方案
  • 最新水果软件FL Studio21.2.0永久激活注册码
  • ubuntu 20.04 server 安装 zabbix
  • Redis集群:Sentinel哨兵模式(图文详解)
  • 02 硬件知识入门(电容)
  • 3分钟在CentOS 7上离线安装Docker
  • Flink之复杂事件处理CEP
  • VSC改造MD编辑器及图床方案分享
  • [UGUI]实现从一个道具栏拖拽一个UI道具到另一个道具栏
  • vue 全局封装文件下载及导入
  • Hadoop学习笔记(HDP)-Part.13 安装Ranger
  • 【开源】基于Vue+SpringBoot的数据可视化的智慧河南大屏
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • CAP 一致性协议及应用解析
  • ES2017异步函数现已正式可用
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • Java基本数据类型之Number
  • Java教程_软件开发基础
  • java正则表式的使用
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • spring cloud gateway 源码解析(4)跨域问题处理
  • uva 10370 Above Average
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • 大整数乘法-表格法
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 力扣(LeetCode)965
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 前端自动化解决方案
  • 微信小程序开发问题汇总
  • 项目实战-Api的解决方案
  • 新书推荐|Windows黑客编程技术详解
  • 用jQuery怎么做到前后端分离
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • MyCAT水平分库
  • Spring第一个helloWorld
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • #define 用法
  • #pragma once与条件编译
  • (c语言)strcpy函数用法
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (转载)Google Chrome调试JS
  • .net对接阿里云CSB服务
  • // an array of int
  • [100天算法】-目标和(day 79)
  • [20170713] 无法访问SQL Server
  • [Android View] 可绘制形状 (Shape Xml)
  • [AUTOSAR][诊断管理][ECU][$37] 请求退出传输。终止数据传输的(上传/下载)