带着问题学习

  1. MVI 中三个字母分别代表什么?
  1. MVI 中三个代表层的关系是怎么样的?
  1. MVI 在 Android 中的实践应该怎么用?
  1. 在 Android 中,可以做到把 MVI 对应的三层都分离开吗?
  1. 什么情况下使用 MVI?
  1. 使用 MVI 有什么需要注意的地方吗?
  1. MVI 与 MVVM 的区别在哪里?

常见的架构

  • MVC
  • MVP
  • MVVM
  • MVI

引入

为什么不继续用MVVM

  • MVVM 中,我们已经实现了 View 层和 Model 层的完全隔离,而且通过 ViewModel 这个中间人,来实现数据和事件传递,从这个角度看,MVVM 绝对是一个足够优秀的架构模式了,但是,为什么后面 Google 又推出了 MVI 架构模式呢?
  • 先来回顾一下,在 MVVM 中,如果 View 层需要监听 ViewModel 层的数据,往往需要对相应的数据注册监听,对于这一点,不管你使用的 LiveData 还是 Flow 的形式,都逃不开。那么问题来了,我们一个 View 里不可能只有少数几个数据需要监听,对于复杂的页面,我们往往需要监听很多个数据状态,这会照成什么问题?
  • 首先,对于 View 层,我们需要对每个数据都注册监听,也就是要多次使用 observe 或者 collect,才能实现对 ViewModel 层的数据监听,而对于 ViewModel 来说,就需要定义多个 LiveData 或者 Flow 来将数据封装进去,并提供给 View 进行监听,对于数据状态少的情况下,这种做法当然没问题,但是数据状态一多,就会使代码看起来很冗余(当然,这也是相对而言的,比如:毕竟从代码格式的角度出发,代码格式还是很统一的)
  • 当然了,MVVM 也不止这一个问题,这里也只是举了一个例子加以说明,方便我们引出 MVI 架构模式而已

MVI

说了这么多,那么何为 MVI 呢?
  • 首先,在 MVI 中,一个 View 只会对应一个状态 state,那么就有人说了,我们页面中可不止一个状态啊?这就不得不提到 MVI 中对于 state 的定义了,在 MVI 中,是将页面中的所有的状态,都封装到一个 state 中,然后在 View 层中进行统一监听即可,这样就能避免我们上面提到的问题了
  • 其次,对于 MVI,其数据流动也不像 MVVM 中那样,需要将 ViewViewMolde 进行双向绑定(在 Android 中最具代表性的就是 DataBinding),而是提倡 单向数据源,也就是,数据永远在一个环形结构中单向流动
  • 基于 单向数据源,另一个 MVI 中的重要理念才能得以实现,也就是 单一可信数据源,何为单一可信数据源呢?通俗点说,就是页面中所有的状态,都只依赖同一个数据源,比如我们在实现一个喜好挑选的页面时,要让一个按钮的点击事件,只在我们同时选择了两个以上爱好[CheckBox]时,才生效,如果我们不使用单一数据源的思想,那么对于该按钮,其点击事件是否生效,实际上就至少要依赖了两个 CheckBox 的状态,这就是数据源不单一了,而如果基于单一可信数据源的话,我们把页面中所有的状态都封装到一个 state 中,此时,对于该按钮来说,只需要依赖这一个 state 即可

为什么在 MVI 中,还有 ViewModel 的出现?

因为 MVI 强调的是数据流动的方向,而不是具体是实现,出现了 ViewModel,其实只是将 MVI 的思想,应用到 MVVM 之中而已,即 MVVM 提供了一套实现方案,而我们在使用 MVI 的时候,只是基于 MVVM 的模式,在其基础上,进行了一些修改,使其满足 MVI 的思想而已

MVI 简介

MVI 三个字母分别代表什么

  • M:Model,代表应用程序的数据模型层,负责存储和管理应用程序的数据
  • V:View,代表用户界面层,负责显示数据以及接收用户输入
  • I:Intent,代表用户的意图,即用户对应用程序的交互操作,例如点击按钮或滚动屏幕等

数据流动图

notion image
notion image
  • 下面是对应的 mermaid 语句:

使用例子/实践

下面用 MVVM 架构模式,实现一个简单获取并显示电影列表的应用

xml文件

主页面xml

RecyclerViewItem 布局xml

定义数据基本格式——Model

定义数据状态——state

定义意图——Intent

定义 RecyclerView.Adapter

定义数据获取层——Repository

定义中间媒介层——ViewModel

定义Activity——View

优缺点

优点

  • 有效地减少应用程序中的状态管理复杂度
  • 可以提高代码的可测试性和可维护性
  • 还可以使用 响应式编程 技术来实现数据流的管理

缺点

  • 虽然 MVI 提倡的是 单一数据源,也意在解决 MVVM 中状态定义存在太多的模板代码的问题,但是,由于是把所有的页面状态都封装到一个 state 中,如果对于页面复杂的情况,将多个状态封装到一次,很有可能就会影响性能了,因为每次其中一个子状态发送了变化,会导致整个 state 被重构

推荐/参考

Leetcode_32-最长有效括号AIDL 简单使用
Loading...