MVP MVVM
Jetpack MVP MVVM
[[MVI学习]]
MVC
(Model-View-Controller)
M 是指逻辑模型,V 是指视图模型,C 则是控制器。通过 controller 的控制去操作 model 层的数据,并且返回给 view 层展示。一个逻辑模型可以对于多种视图模型。
Android 中也可以说采用了当前比较流行的 MVC 框架,在 Android 中:
- 视图层(View):一般采用 XML 文件进行界面的描述,使用的时候可以非常方便的引入,但是用 xml 编写了,又需要在 Acitvity 声明并且实例化。
- 控制层(Controller):控制层的通常落在了众多的 Acitvity 的肩上,要通过 Activity 交割 Model 业务逻辑层处理,并且 activity 还充当了 view 层职责。
- 模型层(Model):java bean、对数据库的操作、对网络等的操作都应该在 Model 里面处理,当然对业务计算等操作也是必须放在的该层的。
MVP
MVP 就是基于 MVC 的模式上的一个演化版本。在 MVC 模式中,Activity 应该是属于 View 这一层。而实质上,它既承担了 View,同时也包含一些 Controller 的东西在里面。随着项目的迭代更新,这对开发很不友好,耦合度也原来越高,项目越来越难维护,而 MVP 就是解决这样的痛点。
MVP 的 model 层相对于 MVC 是一样的,而 activity 和 fragment 不再是 controller 层,而是纯粹的 view 层,所有关于用户事件的转发全部交由 presenter 层处理。
代理模式,交给另一个类做功能。
- view 层: View 对应于 Activity 或者 fragment,负责 View 的绘制以及与用户交互
- Presenter 负责完成 View 于 Model 间的交互
- 本地存储数据,如数据库,文件,SharedPreferences(本质也是文件)
- 内存的缓存或临时数据
- 通过各种网络协议获取的远程数据
管理 Presenter 的生命周期
何时取消网络请求
如果 acitivity 已经关闭了, 而网络操作又没走完. 就会内存泄漏. view 虽然持有 p, 但是也不能在 Activity 的 onDestroy 里面直接的将 p=null 吧,对象=null 也只是断开引用而已,还并不是真的释放。
所以得有个接口告诉 p, 我要挂了, 你也自杀吧,所以:
1 |
|
让所有的 Presenter 都继承 BasePresenter, 然后在 activity(onDestory ())/fragment(onDestoryview ())中相应的生命周期里面调用,在相应的方法里面, 初始化, 结束异步操作, 释放资源, 将 view=null; 而在 activity 里面, 由于 Presenter 并没有 view 的引用了, 所以 p 随着 activity 的销毁也就跟着销毁了.不会造成泄漏等。
在 MVP 中我是在 BaseActivity 中统一把请求取消掉了
MVP 优点
- Model 与 View 完全分离,彻底解耦
- Presenter 复用,可以将一个 Presenter 用于多个视图,而不用改变 Presenter 的逻辑
- 可以实现 View 接口进行逻辑测试(Presenter 的单元测试)
MVP 的缺点
- Model 层过大,做好模块划分,进行接口隔离,在内部进行分层。
- MVP 额外的增加了很多类和接口, 这个可以根据项目业务进行相应地优化。划分 v/p 比较麻烦,一个 activity 引用了 v 以后,那得把 v 里面的方法都实现,即使没有用到.
- V 层与 P 层还是有一定的耦合度。一旦 V 层某个 UI 元素更改,那么对应的接口就必须得改,数据如何映射到 UI 上、事件监听接口这些都需要转变,牵一发而动全身。如果这一层也能解耦就更好了。(其他 mvc 也可以做到,看上面的 demo)
- 当 View 层在卸载时,如果 Model 层中仍有业务 (如子线程未完成、网络请求超时等)没有结束,而 Presenter 层中持有 Model 层和 View 层的引用,那么即使 View 的引用已经释放,由于 Presenter 层的强引用 GC 也无法回收它们。
mvp 中 presenter 的内存泄漏如何解决?
- 弱引用 (WeakReference)的使用: 在 Presenter 中,避免直接持有对 View 层的强引用,而是使用 WeakReference 来代替。这样当 View 层被销毁时,WeakReference 会自动变为 null,垃圾回收器可以正常回收相应的内存。
- 合理管理生命周期: 在 Activity 或 Fragment 的生命周期中,适时地创建和销毁 Presenter 对象。例如,可以在 Activity 的 onCreate 方法中创建 Presenter,在 onDestroy 方法中销毁 Presenter。这样可以确保当 Activity 被销毁时,Presenter 也能被正确释放。
- 取消耗时任务: 如果在 Activity 中启动了耗时的任务 (如网络请求),在 Activity 销毁时需要确保这些任务被取消。这可以通过在 Activity 的 onDestroy 方法中取消请求来实现。
写一个 MVP 例子
1 |
|
MVVM
如何构建Android MVVM 应用框架 - 美团技术团队
[[LiveData、ViewModel]]
官方图
- MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。
- 图中所有的箭头都是单向的,比方说 Activity 指向了 ViewModel,表示》Activity 是依赖于 ViewModel 的,但是反过来 ViewModel 不能依赖于 Activity。其他的几层也是一样的道理,一个箭头就表示一个依赖关系。
依赖关系是不可以跨层的,比方说 UI 控制层不能和仓库层有依赖关系,每一层的组件都只能和它的相邻层交互。
由于 livedata 当更新 viewmodel 层的数据的时候,view 层会相应的变动 ui。
1 |
|