本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
前言
前面我们介绍了MVI架构的基本原理与使用:MVVM 进阶版:MVI 架构了解一下~
MVI架构为了解决MVVM在逻辑复杂时需要写多个LiveData(可变+不可变)的问题,使用ViewState对State集中管理,只需要订阅一个 ViewState 便可获取页面的所有状态
通过集中管理ViewState,只需对外暴露一个LiveData,解决了MVVM模式下LiveData膨胀的问题
但页面的所有状态都通过一个LiveData来管理,也带来了一个严重的问题,即页面不支持局部刷新
虽说如果是RecyclerView可以通过DifferUtil来解决,但毕竟不是所有页面都是通过RecyclerView写的,支持DifferUtil也有一定的开发成本
因此直接使用MVI架构会带来一定的性能损耗,相信这是很多人不愿意用MVI架构的原因之一
本文主要介绍如何通过监听LiveData的属性,来实现MVI架构下的局部刷新
Mavericks框架介绍
Mavericks框架是Airbnb开源的一个MVI框架,Mavericks基于Android Jetpack与Kotlin Coroutines,
主要目标是使页面开发更高效,更容易,更有趣,目前已经在Airbnb的数百个页面上使用
下面我们来看下Mavericks是怎么使用的
1 | kotlin复制代码// 1. 包含页面所有状态的data class |
如上所示,看上去也很简单,主要包括几个模块
- 包括页面所有状态的
Model层,其中的状态全都是不可变的,并且有默认值 - 负责处理业务逻辑的
ViewModel,在其中通过setState来更新页面状态 View层,必须实现MavericksView接口,每当状态刷新时都会回调invalidate函数,在这里渲染UI
可以看出,Mavericks中View层与Model层的交互,也并没有包装成Action,而是直接暴露的方法
上篇文章也的确有很多同学说使用Action交互比较麻烦,看起来Action这层的确可要可不要,Airbnb也没有使用,主要看个人开发习惯吧
支持局部刷新
上面介绍了Mavericks的简单使用,下面我们来看下Mavericks是怎么实现局部刷新的
1 | kotlin复制代码data class UserState( |
- 如上所示,
Mavericks可以只监听State的其中一个属性来实现局部刷新,只有当这个属性发生变化时才触发回调 onEach也可以设置监听模式,主要是为了防止数据倒灌,例如Toast这些只需要弹一次,页面重建时不应该恢复的状态,就适合使用uniqueOnly的监听模式
Mavericks实现属性监听的原理也很简单,我们一起来看下源码
1 | kotlin复制代码fun <VM : MavericksViewModel<S>, S : MavericksState, A> VM._internal1( |
- 主要是通过
map将State转化为它的属性值 - 通过
distinctUntilChanged方法开启防抖,相同的值不会回调,只有值修改了才会回调 - 需要注意的是因为使用了
KProperty1,因此State的承载数据类必须避免混淆
如上,就是Mavericks的基本介绍,想了解更多的同学可参考:github.com/airbnb/mave…
LiveData实现属性监听
上面介绍了Mavericks是怎么实现局部刷新的,但直接使用它主要有两个问题
- 接入起来略微有点麻烦,例如
Fragment必须实现MavericksView,有一定接入成本 Mavericks的局部刷新是通过Flow实现的,但相信大多数人用的还是LiveData,有一定学习成本
下面我们就来看下LiveData怎么实现属性监听
1 | kotlin复制代码//监听一个属性 |
- 如上所示,主要是添加一个扩展方法,也是通过
distinctUntilChanged来实现防抖 - 如果需要监听多个属性,例如两个属性有其中一个变化了就触发刷新,也支持传入两个属性
- 需要注意的是
LiveData默认是不防抖的,这样改造后就是防抖的了,所以传入相同的值是不会回调的 - 同时需要注意下承载
State的数据类需要防混淆
简单使用
上面介绍了LiveData如何实现属性监听,下面看下简单的使用
1 | kotlin复制代码//页面状态,需要避免混淆 |
如上所示,其实使用起来也很简单方便
ViewModel只需对外暴露一个ViewState,避免了定义多个可变不可变LiveData的问题View层支持监听LiveData的一个属性或多个属性,支持局部刷新
总结
本文主要介绍了MVI架构下如何实现局部刷新,并重点介绍了Mavericks的基本使用与原理,并在其基础上使用LiveData实现了属性监听与局部刷新
通过以上方式,解决了MVI架构的性能问题,实现了MVI架构的更佳实践
如果你的ViewModel中定义了多个可变与不可变的LiveData,就算你不使用MVI架构,支持监听LiveData属性相信也可以帮助你精简一定的代码
如果本文对你有所帮助,欢迎点赞关注Star~
项目地址
本文所有代码可见:github.com/shenzhen201…
本文转载自: 掘金