Android 开发发展到今天已经相当成熟了,各种架构大家也都耳熟能详,如 MVC,MVP,MVVM 等,其中 MVVM 更是被官方推荐,成为 Android 开发中的显学。不过软件开发中没有银弹,MVVM 架构也不是尽善尽美的,在使用过程中也会有一些不太方便之处,而MVI可以很好的解决一部分 MVVM 的痛点。
本文主要包括以下内容
需要重点指出的是,标题中说 MVI 架构是MVVM的进阶版是指 MVI 在 MVVM 非常相似,并在其基础上做了一定的改良,并不是说 MVI 架构一定比 MVVM 适合你的项目 各位同学可以在分析比较各个架构后,选择合适项目场景的架构
MVC 是个古老的 Android 开发架构,随着 MVP 与 MVVM 的流行已经逐渐退出历史舞台,我们在这里做一个简单的介绍,其架构图如下所示:
MVC 架构主要分为以下几部分
由于 android 中 xml 布局的功能性太弱,Activity 实际上负责了 View 层与 Controller 层两者的工作,所以在 android 中 mvc 更像是这种形式:
因此 MVC 架构在 android 平台上的主要存在以下问题:
由于 MVC 架构在 Android 平台上的一些缺陷,MVP 也就应运而生了,其架构图如下所示
MVP 架构主要分为以下几个部分
我们可以看到,MVP 解决了 MVC 的两个问题,即 Activity 承担了两层职责与 View 层与 Model 层耦合的问题
但 MVP 架构同样有自己的问题
MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。唯一的区别是,它采用双向数据绑定(data-binding):View 的变动,自动反映在 ViewModel,反之亦然
MVVM 架构图如下所示:
可以看出 MVVM 与 MVP 的主要区别在于,你不用去主动去刷新 UI 了,只要 Model 数据变了,会自动反映到 UI 上。换句话说,MVVM 更像是自动化的 MVP。
MVVM 的双向数据绑定主要通过 DataBinding 实现,不过相信有很多人跟我一样,是不喜欢用 DataBinding 的,这样架构就变成了下面这样
要了解 MVI 架构,我们首先来了解下 MVVM 架构有什么不足 相信使用 MVVM 架构的同学都有如下经验,为了保证数据流的单向流动,LiveData 向外暴露时需要转化成 immutable 的,这需要添加不少模板代码并且容易遗忘,如下所示
class TestViewModel : ViewModel() {
//为保证对外暴露的LiveData不可变,增加一个状态就要添加两个LiveData变量
private val _pageState: MutableLiveData<PageState> = MutableLiveData()
val pageState: LiveData<PageState> = _pageState
private val _state1: MutableLiveData<String> = MutableLiveData()
val state1: LiveData<String> = _state1
private val _state2: MutableLiveData<String> = MutableLiveData()
val state2: LiveData<String> = _state2
//...
}
如上所示,如果页面逻辑比较复杂,ViewModel 中将会有许多全局变量的 LiveData ,并且每个 LiveData 都必须定义两遍,一个可变的,一个不可变的。这其实就是我通过 MVVM 架构写比较复杂页面时最难受的点。
其次就是 View 层通过调用 ViewModel 层的方法来交互的,View 层与 ViewModel 的交互比较分散,不成体系
小结一下,在我的使用中,MVVM 架构主要有以下不足
MVI 与 MVVM 很相似,其借鉴了前端框架的思想,更加强调数据的单向流动和唯一数据源,架构图如下所示
其主要分为以下几部分
MVI 强调数据的单向流动,主要分为以下几步:
数据永远在一个环形结构中单向流动,不能反向流动:
上面简单的介绍了下 MVI 架构,下面我们一起来看下具体是怎么使用 MVI 架构的
我们使用 ViewModel 来承载 MVI 的 Model 层,总体结构也与MVVM类似,主要区别在于 Model 与 View 层交互的部分
ViewState 承载页面的所有状态,ViewEvent 则是一次性事件,如 Toast 等,如下所示
data class MainViewState(val fetchStatus: FetchStatus, val newsList: List<NewsItem>)
sealed class MainViewEvent {
data class ShowSnackbar(val message: String) : MainViewEvent()
data class ShowToast(val message: String) : MainViewEvent()
}
class MainViewModel : ViewModel() {
private val _viewStates: MutableLiveData<MainViewState> = MutableLiveData()
val viewStates = _viewStates.asLiveData()
private val _viewEvents: SingleLiveEvent<MainViewEvent> = SingleLiveEvent()
val viewEvents = _viewEvents.asLiveData()
init {
emit(MainViewState(fetchStatus = FetchStatus.NotFetched, newsList = emptyList()))
}
private fun fabClicked() {
count++
emit(MainViewEvent.ShowToast(message = "Fab clicked count $count"))
}
private fun emit(state: MainViewState?) {
_viewStates.value = state
}
private fun emit(event: MainViewEvent?) {
_viewEvents.value = event
}
}
如上所示
private fun initViewModel() {
viewModel.viewStates.observe(this) {
renderViewState(it)
}
viewModel.viewEvents.observe(this) {
renderViewEvent(it)
}
}
如上所示,MVI 使用 ViewState 对 State 集中管理,只需要订阅一个 ViewState 便可获取页面的所有状态,相对 MVVM 减少了不少模板代码。
class MainActivity : AppCompatActivity() {
private fun initView() {
fabStar.setOnClickListener {
viewModel.dispatch(MainViewAction.FabClicked)
}
}
}
class MainViewModel : ViewModel() {
fun dispatch(action: MainViewAction) =
reduce(viewStates.value, action)
private fun reduce(state: MainViewState?, viewAction: MainViewAction) {
when (viewAction) {
is MainViewAction.NewsItemClicked -> newsItemClicked(viewAction.newsItem)
MainViewAction.FabClicked -> fabClicked()
MainViewAction.OnSwipeRefresh -> fetchNews(state)
MainViewAction.FetchNews -> fetchNews(state)
}
}
}
如上所示,View 通过 Action 与 ViewModel 交互,通过 Action 通信,有利于 View 与 ViewModel 之间的进一步解耦,同时所有调用以 Action 的形式汇总到一处,也有利于对行为的集中分析和监控
本文主要介绍了 MVC,MVP,MVVM 与 MVI 架构,目前 MVVM 是官方推荐的架构,但仍然有以下几个痛点
而 MVI 可以比较好的解决以上痛点,它主要有以下优势
当然 MVI 也有一些缺点,比如
软件开发中没有银弹,所有架构都不是完美的,有自己的适用场景,读者可根据自己的需求选择使用。但通过以上的分析与介绍,我相信使用 MVI 架构代替没有使用 DataBinding 的 MVVM 是一个比较好的选择~
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/Ofc15Aj3LXYIUgI0XbUv5w
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。