MVC 架构演进
Android 原生开发中 对MVC 开发机构的划分:
View 层
XML 布局文件描述
Controller 层
通常是是指Activity,Fragment 或者某个View控件;
Model 层
数据处理部分,从网络获取,磁盘获取,缓存获取等;
优点:
易于理解,层次简单;
不足:
Controller层 中,Activity 等耦合了业务逻辑,导致代码臃肿,维护成本高,扩展困难。
MVP模式
Presenter ——交互中间人
引入Presenter 层,主要作为沟通View和Model的桥梁,从Model层检索数据后,
返回给View层,使得View和Model 之间的没有耦合,也将业务逻辑从View 角色上抽离出来。
View—— 用户界面
View 通常是指Activity,Fragment 或者某个View 控件,持有 一个Presenter 成员变量,通常View 需要实现一个逻辑接口,将View 上的操作通过转交给Presenter 进行实现,最后,Presenter 调用 View 逻辑接口 将结果返回给View 元素。
Model —— 数据的存取
Presenter 通过Model 层存储,获取数据,Model 就像一个数据仓库。
基本设计思路
封装基础 MVPBaseActivity
封装基础 MVPBaseFragment
解决网络回调更新UI
在网络回调里面,Presenter 通过getView().isAttach() 判断UI是否已经销毁 判断是否要执行UI更新操作。
解决内存泄漏问题
关联View attachView 解关联 detachView
对于Activity
在 onCreate() attachView
在 onDestroy() detachView
对于Fragment
在onViewCreated attachView
在 onDestroyView detachView
对View的引用是弱引用,保证GC时候 能够释放弱引用。
什么时候不调用 onDestroy?
从后台强杀分两种情况:
第一种:当前仅有一个activity,这时候,强杀,是会执行onDestroy方法的;
第二种:栈里面的第一个没有销毁的activity会执行ondestroy方法,其他的不会执行。
比如说:从mainactivity跳转到activity-A(或者继续从activity-A再跳转到activity-B),这时候,从后台强杀,只会执行mainactivity的onDestroy方法,activity-A(以及activity-B)的onDestroy方法都不会执行;
MVVM 进阶
MvvM 与 MVP 非常相似,唯一的区别是 View 和 Model 进行双向绑定( data 一 binding ) ,两者之间有一方发生变化则会反应到另一方上。而 MVP 与 MVVM 的主要区别则是, MVP 中的 View 更新需要通过 Presenter ,而 MVVM 则不需要,因为 View 与 Model 进行了双向绑定,数据的修改会直接反应到 View 角色上,而view 的修改也会导致数据的变更。此时, ViewModel 角色需要做的只是业务逻辑的处理,以及修改 view 或者 Model 的状态。 MVVM 模式有点像 ListView 与 Adapter 、数据集的关系,这个 Adapter 就是 viewModel 角色,它与 View 进行了绑定,又与数据集进行了绑定,当数据集合发生变化时,调用 Adapter 的 notifyDatasetChanged 之后 View 就直接更新,它们之间没有直接的耦合,使得 ListView 变得更为灵活。
MVP 和MVVM 选型
MVP 改造 不需要引入新的库,而且已经能够满足当前需要。
MVVM 需要引入 databinding 库,有接入成本和学习成本;
后期可以使用Jetpack 组件中 ViewModel 来实现MVVM ,未来可能考虑 切换到MVVM。
MVVM 和 MVI
MVVM 缺陷
- MVVM 与 MVP 的主要区别在于双向数据绑定,但由于很多人(比如我)并不喜欢使用 DataBindg,其实并没有使用 MVVM 双向绑定的特性,而是单一数据源
- 当页面复杂时,需要定义很多 State,并且需要定义可变与不可变两种,状态会以双倍的速度膨胀,模板代码较多且容易遗忘
- View 与 ViewModel 通过 ViewModel 暴露的方法交互,比较零乱难以维护。
MVI 优势
而 MVI 可以比较好的解决以上痛点,它主要有以下优势
- 强调数据单向流动,很容易对状态变化进行跟踪和回溯
- 使用 ViewState 对 State 集中管理,只需要订阅一个 ViewState 便可获取页面的所有状态,相对 MVVM 减少了不少模板代码
- ViewModel 通过 ViewState 与 Action 通信,通过浏览 ViewState 和 Aciton 定义就可以理清 ViewModel 的职责,可以直接拿来作为接口文档使用。
当然 MVI 也有一些缺点,比如 - 所有的操作最终都会转换成 State,所以当复杂页面的 State 容易膨胀
- state 是不变的,因此每当 state 需要更新时都要创建新对象替代老对象,这会带来一定内存开销
参考资料
《Android 开发模式解析和实战》