从MVVM到MVI:Android-Jetpack-Demo中的架构演进与最佳实践
Android-Jetpack-Demo是一个专注于快速入门Android Jetpack&Compose以及相关Kotlin、MVVM/MVI等独立架构App基础技能的项目。本文将深入探讨该项目中从MVVM到MVI的架构演进过程,并分享最佳实践,帮助开发者更好地理解和应用这两种架构模式。
一、MVVM架构在Android-Jetpack-Demo中的应用
MVVM(Model-View-ViewModel)架构模式在Android开发中得到了广泛应用,Android-Jetpack-Demo也不例外。Jetpack的其他组件在同一个项目module内共用,同时使用MVVM的架构设计模式,来简单实现一个组合使用各个库的示例。
在MVVM架构中,ViewModel起着关键作用,它作为UI与数据的桥梁层,用于业务逻辑处理。例如,在jetpack/src/main/java/org/zhiwei/jetpack/components/ui/JetpackViewModel.kt中,我们可以看到ViewModel的具体实现。
1.1 ViewModel的获取与使用
在Android-Jetpack-Demo中,获取ViewModel有两种常见方式:
//在fragment中获取它所依附的activity所持有的viewModel,得到的是activity的vm对象
private val vm: JetpackViewModel by activityViewModels()
//这是fragment关联一个自身持有的vm的对象,多个fragment用此方式得到的vm,是不同的对象,所以数据不共享
private val vm: JetpackViewModel by ViewModels()
第一种方式适合同一activity下多个fragment之间通过vm来共享数据,第二种方式则适用于fragment自身持有独立的vm对象。
1.2 LiveData的数据观察
LiveData是MVVM架构中实现数据观察的重要组件。在jetpack/jetpack笔记速览.md中,详细介绍了LiveData的使用方法,包括map、switchMap等转换操作,以及MediatorLiveData的使用。
private val _liveStudentScore = MutableLiveData<String>()
//一般mutable的都是可修改的,开发习惯,可修改的私有,对外提供不可变的
val liveScore: LiveData<String> = _liveStudentScore
//map函数,就是将一种数据类型,按照你需要的规则,转化为另一种数据类型,然后得到一个新的liveData,可用于观察
val map = _liveStudentScore.map { it.length }
//switchMap是将上游livedata的数据,以新的liveData的形式重新发射出去
val switchMap = _liveStudentScore.switchMap { liveData { emit(it.length) } }
1.3 DataBinding的应用
DataBinding是实现MVVM架构的重要工具,虽然在新项目中可能会被Compose替代,但在Android-Jetpack-Demo中仍有独立module作为代码示例。在jetpack/databinding/src/main/java/org/zhiwei/jetpack/databinding/activity/CommonUseActivity.kt中,有相关注释说明:
//todo 一般来说,MVVM模式下,这些数据都是在viewModel中配置,然后binding.vm = viewmodel即可
二、MVI架构的引入与实现
随着项目的发展,为了更好地处理复杂的业务逻辑和UI状态,Android-Jetpack-Demo引入了MVI(Model-View-Intent)架构。在示例代码中会插入MVI和MVVM的架构实现,全新架构设计模块化分组演示Jetpack重要组件的功能使用,以及MVI架构和组件化、项目构建等。
2.1 MVI架构的核心思想
MVI架构的核心思想是将UI状态和用户意图明确分离。与MVVM相比,MVI更加注重单向数据流,所有的状态变化都通过明确的意图(Intent)触发,经过处理后产生新的状态(State),并反馈给UI。
2.2 MVI与MVVM的对比
MVI和MVVM都旨在分离关注点,但MVI通过严格的单向数据流和不可变的状态对象,使应用的状态变化更加可预测和可调试。在MVVM中,ViewModel可能会暴露多个LiveData对象,而MVI通常会将所有状态封装在一个单一的State对象中。
2.3 MVI在项目中的实践
在Android-Jetpack-Demo中,MVI架构的实现可以在相关的模块中找到。例如,在处理网络请求或本地数据库操作时,MVI架构可以更好地管理加载、成功、失败等不同状态。在jetpack/src/main/java/org/zhiwei/jetpack/components/room/StudentRepo.kt中,有这样的注释:
// private val networkSource:NetworkSource,//这里就是模拟说有个网络加载数据的方式,在MVVM或MVI等设计架构中
这表明在数据仓库层,项目考虑了不同架构模式下的数据获取方式。
三、架构演进的最佳实践
3.1 模块化与组件化
Android-Jetpack-Demo后续会添加模块化与组件化的项目演示。模块化可以将不同的功能模块分离,便于团队协作和代码复用。例如,compose模块专注于UI的实现,jetpack模块则包含了各种Jetpack组件的应用。
3.2 合理使用Jetpack组件
无论是MVVM还是MVI架构,都需要合理使用Jetpack组件。Lifecycle、LiveData、ViewModel三者配合使用是常见的模式,Room用于本地数据库操作,WorkManager处理后台任务,Navigation管理页面导航,Paging实现分页加载等。
在jetpack/jetpack笔记速览.md中,对这些组件的使用都有详细的介绍和示例代码。
3.3 选择适合的架构模式
MVVM和MVI各有优缺点,开发者应根据项目的实际需求选择适合的架构模式。对于简单的UI界面,MVVM可能足够;对于复杂的业务逻辑和频繁变化的UI状态,MVI可能是更好的选择。Android-Jetpack-Demo同时包含了这两种架构的实现,为开发者提供了学习和参考的范例。
四、总结
Android-Jetpack-Demo项目展示了从MVVM到MVI的架构演进过程,通过模块化分组演示了Jetpack重要组件的功能使用。无论是MVVM还是MVI,都强调了关注点分离和数据驱动UI的思想。开发者可以通过学习该项目,深入理解这两种架构模式的实现方式和最佳实践,从而构建更加健壮、可维护的Android应用。
要开始使用该项目,你可以通过以下命令克隆仓库:
git clone https://gitcode.com/gh_mirrors/an/android-jetpack-demo
希望本文能够帮助你更好地理解Android架构的演进和实践,为你的项目开发提供有益的参考。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考






