Android MVI

532 阅读3分钟

架构

MVI借鉴了前端框架的思想,更加强调数据的单向流动和唯一数据源,架构图如下所示 image.png

其主要分为以下几部分

  1. Model: 与MVVM中的Model不同的是,MVIModel主要指UI状态(State)。例如页面加载状态、控件位置等都是一种UI状态
  2. View: 与其他MVX中的View一致,可能是一个Activity或者任意UI承载单元。MVI中的View通过订阅Model的变化实现界面刷新
  3. Intent: 此Intent不是ActivityIntent,用户的任何操作都被包装成Intent后发送给Model层进行数据请求

单向数据流

MVI强调数据的单向流动,主要分为以下几步:

  1. 用户操作以Intent的形式通知Model
  2. Model基于Intent更新State
  3. View接收到State变化刷新UI。

数据永远在一个环形结构中单向流动,不能反向流动:

上面简单的介绍了下MVI架构,下面我们一起来看下具体是怎么使用MVI架构的

MVI架构实战

总体架构图


我们使用ViewModel来承载MVIModel层,总体结构也与MVVM类似,主要区别在于ModelView层交互的部分

  1. Model层承载UI状态,并暴露出ViewStateView订阅,ViewState是个data class,包含所有页面状态
  2. View层通过Action更新ViewState,替代MVVM通过调用ViewModel方法交互的方式

总结

目前MVVM是官方推荐的架构,但仍然有以下几个痛点

  1. MVVMMVP的主要区别在于双向数据绑定,但由于很多人并不喜欢使用DataBindg,其实并没有使用MVVM双向绑定的特性,而是单一数据源
  2. 当页面复杂时,需要定义很多State,并且需要定义可变与不可变两种,状态会以双倍的速度膨胀,模板代码较多且容易遗忘
  3. ViewViewModel通过ViewModel暴露的方法交互,比较零乱难以维护

MVI可以比较好的解决以上痛点,它主要有以下优势

  1. 强调数据单向流动,很容易对状态变化进行跟踪和回溯
  2. 使用ViewStateState集中管理,只需要订阅一个 ViewState 便可获取页面的所有状态,相对 MVVM 减少了不少模板代码
  3. ViewModel通过ViewStateAction通信,通过浏览ViewStateAciton 定义就可以理清 ViewModel 的职责,可以直接拿来作为接口文档使用。

当然MVI也有一些缺点,比如

  1. 所有的操作最终都会转换成State,所以当复杂页面的State容易膨胀
  2. state是不变的,因此每当state需要更新时都要创建新对象替代老对象,这会带来一定内存开销


作者:程序员江同学
链接:juejin.cn/post/702262… 来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。