什么是MVP,MVP其实就是一种架构模式,是“MVC”的进化而来的,我第一次下载demo来看的时候,看得晕头晕脑的,看了几遍后,稍微有点门路了,决定自己写个demo,妈呀,太难了。(这里介绍一片博文:http://blog.csdn.net/lmj623565791/article/details/46596109,张鸿洋大神写的,很不错 )
M:提供数据、实体模式或者处理些业务逻辑。
V:视图,展现给用户看的,并与之交互。
P:协调者,是M、V的桥梁,负责完成它们之间的交互。
这里盗用鸿洋大神的两张图,请原谅我懒得画,呵呵。
这张图可以很清楚的表达出整个MVP的流程,还有一张是关于MVC和MVP的区别,也很容易理解,请看下图:
好了,其实理论就是这些,下面来看看是怎么实现的:
首先MVP三个基类(接口):
public interface BaseModel {
}
public interface BaseView {
Activity getActivity();
}
public abstract class BasePresenter<T extends BaseView, M extends BaseModel> {
public T mView;
public M mModel;
public BasePresenter(T view, M model) {
if (null == view) {
throw new NullPointerException("view must not null");
}
this.mView = view;
this.mModel = model;
}
public void detachView() {
mView = null;
}
}
还有一个Activity的基类:
public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity {
protected T mPresenter;
public abstract T createPresenter();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mPresenter = createPresenter();
super.onCreate(savedInstanceState);
}
public Activity getActivity() {
return this;
}
@Override
protected void onDestroy() {
if (null != mPresenter) {
mPresenter.detachView();
}
super.onDestroy();
}
}
项目的结构如下图:
其中的MainActivity就是V,MainModel就是M,MainPresenter就是P,另外我们先来看看MainContract这个契约类,代码如下:
public interface MainContract {
interface View extends BaseView {
void setValue(String value);
}
interface Model extends BaseModel {
void getValue(ICallBack iCallBack, Context context);
}
abstract class Presenter extends BasePresenter<View, Model> {
public Presenter(View view, Model model) {
super(view, model);
}
public abstract void getValue();
}
}
该类定义了我们所需要的M、V、P接口或者类,MainActivity实现了View接口作为V层,MainModel实现了Model接口作为M层,MainPresenter继承了抽象类Presenter作为P层。现在我们先来看看Model的代码:
public class MainModel implements MainContract.Model {
@Override
public void getValue(final ICallBack iCallBack, final Context context) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
iCallBack.success(context.getString(R.string.value));
}
}).start();
}
}
model就简单的返回一个字符串,为了方便,我们这里以回调形式返回。
下面是View的代码:
package com.sonny.mvp;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.sonny.mvp.base.BaseActivity;
public class MainActivity extends BaseActivity<MainContract.Presenter> implements MainContract.View, View.OnClickListener {
private TextView mTvValue;
@Override
public MainContract.Presenter createPresenter() {
return new MainPresenter(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn_get_data).setOnClickListener(this);
mTvValue = (TextView) findViewById(R.id.tv_mvp_value);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_get_data:
mPresenter.getValue();
break;
}
}
@Override
public void setValue(final String value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mTvValue.setText(value);
}
});
}
}
既然P作为M、V的桥梁,那么它就拥有M、V的实例,所以我们在View实例化Presenter对象时,会把View传给它,这样我们就把P层和V层关联起来了。
下面是P层的代码:
public class MainPresenter extends MainContract.Presenter {
public MainPresenter(MainContract.View view) {
super(view, new MainModel());
}
@Override
public void getValue() {
mModel.getValue(new ICallBack() {
@Override
public void success(String value) {
mView.setValue(value);
}
}, mView.getActivity());
}
}
该层持有V和M的对象。
getValue方法会调用M的方法并返回数据,成功后调用V层的方法把数据现象出来,这样我们Presenter就完成了M、V的交互。
代码我放在:https://github.com/linqssonny/MVP,欢迎大家下载查阅,如有错误之处请指正,QQ:252624617.