Android MVP简单实现
-
MVC:Model-View-Controller,经典模式,很容易理解,主要缺点有两个:
1、View对Model的依赖,会导致View也包含了业务逻辑;
2、Controller会变得很厚很复杂。M --> Model(存放数据模型) V --> View(存放activity 和一些自定义的View) C --> Cotroller(业务逻辑处理)
-
MVP:Model-View-Presenter,MVC的一个演变模式,将Controller换成了Presenter,主要为了解决上述第一个缺点,将View和Model解耦,不过第二个缺点依然没有解决。
M --> Model(存放数据模型与业务逻辑) V --> View(存放activity 和一些自定义的View) P --> Presenter(主要负责与View和Model的交互) 优点: 1、view和model之间耦合度降低; 2、便于单元测试; 3、代码复用率提高; 4、代码框架更适合于迭代开发; 缺点: 主要表现在每个view都有presenter,类相对比较多
MVP 模式(Model-View-Presenter)可以说是 MVC 模式(Model-View-Controller)在 Android 开发上的一种变种、进化模式。
在 MVC 模式中,Activity 应该是属于 View 这一层。而实质上,它既承担了 View,同时也包含一些 Controller 的东西在里面。这对于开发与维护来说不太友好,耦合度大高了。把 Activity 的 View 和 Controller 抽离出来就变成了 View 和 Presenter,这就是 MVP 模式。
Activity 和Fragment 视为View层,负责处理 UI。
Presenter 为业务处理层,既能调用UI逻辑,又能请求数据,该层为纯Java类,不涉及任何Android API。
Model 层中包含着具体的数据请求,数据源。
三层之间调用顺序为view->presenter->model。
具体实例:
View接口:
View接口是Activity与Presenter层的中间层,它的作用是根据具体业务的需要,为Presenter提供调用Activity中具体UI逻辑操作的方法。
public interface IMvpview {
/**
* 显示正在加载进度框
*/
void showLoading();
/**
* 隐藏正在加载进度框
*/
void hideLoading();
/**
* 当数据请求成功后,调用此接口显示数据
*
* @param data 数据源
*/
void showData(String data);
/**
* 当数据请求失败后,调用此接口提示
*
* @param msg 失败原因
*/
void showFailureMessage(String msg);
/**
* 当数据请求异常,调用此接口提示
*/
void showErrorMessage();
}
Presenter接口:
presenter接口是presenter和model之间的中间层,它的作用是为Model层提供调用Presenter层的方法。
public interface IMvpPresenter {
void onSuccess(String data);
void onFailure(String msg);
void onError();
void onComplete();
}
Model接口
Model接口作用是提供具体业务逻辑处理的方法
public interface IMvpModel {
/**
* 数据请求
*
* @param data
*/
void getNetData(String data);
}
Activity类
public class MainActivity extends AppCompatActivity implements IMvpview, View.OnClickListener {
private MvpPresenter mvpPresenter;
//进度条
ProgressDialog progressDialog;
TextView text;
Button btn1, btn2, btn3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn3 = (Button) findViewById(R.id.btn3);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
// 初始化进度条
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage("正在加载数据");
mvpPresenter = new MvpPresenter();
mvpPresenter.attachView(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn1:
mvpPresenter.getData("normal");
break;
case R.id.btn2:
mvpPresenter.getData("failure");
break;
case R.id.btn3:
mvpPresenter.getData("failure");
break;
}
}
@Override
public void showLoading() {
if (!progressDialog.isShowing()) {
progressDialog.show();
}
}
@Override
public void hideLoading() {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
@Override
public void showData(String data) {
text.setText(data);
}
@Override
public void showFailureMessage(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
text.setText(msg);
}
@Override
public void showErrorMessage() {
Toast.makeText(this, "网络请求数据出现异常", Toast.LENGTH_SHORT).show();
text.setText("网络请求数据出现异常");
}
@Override
protected void onDestroy() {
super.onDestroy();
// 断开View引用
mvpPresenter.detachView();
}
}
Presenter类
public class MvpPresenter implements IMvpPresenter {
private IMvpview iMvpview;
private MvpModel mvpModel;
public void getData(String params) {
iMvpview.showLoading();
mvpModel.getNetData(params);
}
/**
* 绑定view,一般在初始化中调用该方法
*/
public void attachView(IMvpview iMvpview) {
this.iMvpview = iMvpview;
mvpModel = new MvpModel(this);
}
/**
* 断开view,一般在onDestroy中调用
*/
public void detachView() {
this.iMvpview = null;
}
/**
* 是否与View建立连接
* 每次调用业务请求的时候都要出先调用方法检查是否与View建立连接
*/
public boolean isViewAttached() {
return iMvpview != null;
}
@Override
public void onSuccess(String data) {
if (isViewAttached()) {
iMvpview.showData(data);
}
}
@Override
public void onFailure(String msg) {
if (isViewAttached())
iMvpview.showFailureMessage(msg);
}
@Override
public void onError() {
if (isViewAttached())
iMvpview.showErrorMessage();
}
@Override
public void onComplete() {
if (isViewAttached())
iMvpview.hideLoading();
}
}
Model类
public class MvpModel implements IMvpModel {
private IMvpPresenter iMvpPresenter;
public MvpModel(IMvpPresenter iMvpPresenter) {
this.iMvpPresenter = iMvpPresenter;
}
/**
* 获取网络接口数据
*
* @param param 请求参数
*/
@Override
public void getNetData(final String param) {
// 利用postDelayed方法模拟网络请求数据的耗时操作
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
switch (param) {
case "normal":
iMvpPresenter.onSuccess("根据参数" + param + "的请求网络数据成功");
break;
case "failure":
iMvpPresenter.onFailure("请求失败:参数有误");
break;
case "error":
iMvpPresenter.onError();
break;
}
iMvpPresenter.onComplete();
}
}, 2000);
}
}