前言
通过上篇的例子可以看出来,在MVC中,Activity作为Controller层,首先要加载应用布局,然后初始化界面,View的操作,用户逻辑基本上都在Activity开发,导致Activity的代码非常拥挤,并且MVC模型Model层和View层是可以直接交流的,这就导致项目耦合性提升,这会给后期开发和维护造成困难。
经过一系列的演变MVP(Model-View-Presenter)也应运而生。
结构
- Model:模型层-面向需求模型,数据模型。对应Bean实体,SqliteDataBase。
- View:对应Activity,Fragment,自定义View等java文件,这里的Activity负责View的绘制,显示,响应用户的操作。
- Presenter:Presenter层将原来的Controller业务逻辑转移到Presenter层,同时断绝View和Model层的联系,达到解耦的目的。
流程关系
- View收到用户的操作,把用户的操作交给Presenter。
- Presenter控制Model进行业务逻辑处理。
- Presenter处理完毕后,数据封装到Model。
- Presenter收到通知后,再更新View。
代码展示
我们就写一个简单的业务功能,情景是用户点击屏幕上的按钮,去网络上请求一张图片。
工程目录:
优点:
- View层与model层完全分离
- 所有逻辑处理和交互都在presenter中
- MVP分层较为严谨
缺点:
造成类数量爆炸,代码复杂度和学习成本高,在某些场景下presenter的复用会产生接口冗余。
改进MVP
在以上代码中,我们可以做个测试,在DownLoaderPresenter中开启一个线程,退出应用后GC,分析发现MainActivity依旧在,容易造成内存泄漏。
下面我们来进行代码的改进。在Presenter中新增一个弱引用WeakReference,同时使用了泛型和抽象类对之前的代码进行了优化。
public abstract class BasePresenter<M extends BaseModel,V extends BaseView,CONTRACT> {
protected M m;
private WeakReference<V> vWeakReference;
public BasePresenter() {
m = getModel();
}
public void bindView(V v) {
vWeakReference = new WeakReference<>(v);
}
public void unBindView() {
if (vWeakReference!=null){
vWeakReference.clear();
vWeakReference = null;
System.gc();
}
}
protected V getView(){
if (vWeakReference != null) {
return vWeakReference.get();
}
return null;
}
public abstract CONTRACT getContract();
public abstract M getModel();
}
改进后发现同样的操作,进行内存分析后Activity不存在了。
至此,MVP讲解完毕。
Demo源码地址
网友评论