近日在学习MVP架构,今天读到一篇很好的文章,实现了一个很简单的MVP架构,收获良多,所以很想记下来分享。希望对大家有所帮助。
明确关系
在MVP架构之中,presenter最为重要(个人感觉),通俗一点说就是,presenter是boss,而model和view是小弟,都要接受presenter的管理。
不多说废话,先把三者搞出来
public class Presenter {
}
public interface IModel {
}
public interface IView {
}
举个栗子
那么以什么为例子呢?就再举个最简单的吧,以点击一个屏幕上面的按钮,然后弹出一个Toast为例进行MVP的实现。
废话不多说,拆!
我们把这个场景的对象拆解为人和activity以及手机系统
-------为了快速写出mvp,会有误导,其实真实的任务分配时展示任务分配给view;数据的操作任务分给model,这一环其实可有可无;剩余的所有任务逻辑通通分配给presenter(所以人家是老大啊)。朋友们可以之后回头回味一下~ -------
人
把人要做的事情假如presenter接口之中,这个用例之中,人要做的事点击按钮,那么加一个clickButton方法:
public class Presenter {
void clickButton(){
}
}
activity
activity在Mvp之中充当V的,也就是view层,我们所有的view的初始化全部都在activity 之中进行。因此我们把界面展示所需做的事情加入iew接口之中 在这个用例之中,view需要做的是,当点击了button之后,会弹出一个Toast,因此我们给出接口方法showToast:
public class IView{
void showToast(String content);
}
手机系统
除了上面两者之外,其他的就是手机系统要干的事情了。那么剩下的制造Toast的内容就是手机系统去做的:
public interface IModel {
/**
* 除了人和activity之外,其他的就是手机系统要干的事情
* 那剩下的至少toast内容就是由手机系统去做的
* */
String makeToast();
}
关联MVP
由于presenter要管理两者,所以要有他俩的实例,自然而然地想到通过构造方法去传递:
public class Presenter {
//由于Presenter需要关注Model和View层,所以他必须有两者的实例
IView iView;
IModel iModel;
/**
* 通过构造方法传递Model和View层
* */
public Presenter(IView view,IModel model){
iView=view;
iModel=model;
}
接口实现
public class ToastContentMaker implements IModel{
@Override
public String makeToast() {
return "MVP架构测试";
}
}
public class MainActivity extends AppCompatActivity implements IView{ @Override public void showToast(String content) { Toast.makeText(this,content,Toast.LENGTH_LONG).show(); } }
添加presenter逻辑
将presenter逻辑加入activity之中
public class MainActivity extends AppCompatActivity implements IView{
Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
presenter=new Presenter(this,new ToastContentMaker());
findViewById(R.id.Test_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.clickButton();
}
});
}
}
更改一下presenter之中的clickButton方法
void clickButton(){
iView.showToast(iModel.makeToast());
}
总结流程
1. 一个p类,两个接口(定接口)
2. 提供view方法放view接口,数据操作的方法放在model接口,其他方法(分方法)
3.Activity实现view接口
4.自定义数据操作实现model接口
5.p类持有两个接口的实例(这里会有一些隐患,见文末)
6.Activity初始化p类,并用p类方法代替业务逻辑
7.顺着业务逻辑去p类,调用V和M的接口方法执行业务操作。
写在最后的
流程五中有一个小隐患:写mvp的时候,presenter会持有view,如果presenter有后台异步的长时间的动作,比如网络请求,这时如果返回退出了Activity,后台异步的动作不会立即停止,这里就会有内存泄漏的隐患,所以会在presenter中加入一个销毁view的方法。现在就在之前的项目中做一下修改:
/**
* 写mvp的时候,presenter会持有view,如果presenter有后台异步的长时间的动作,
* 比如网络请求,这时如果返回退出了Activity,
* 后台异步的动作不会立即停止,这里就会有内存泄漏的隐患,
* 所以会在presenter中加入一个销毁view的方法。
* 可以将view层置为null
* */
void onDestroy(){
iView=null;
}
//退出时销毁持有的activity
@Override
protected void onDestroy() {
super.onDestroy();
//退出时销毁持有Activity
presenter.onDestroy();
}