MVC、MVP概念网上都有,不再重复,这里直接展示MVP架构怎么搭建的。不考虑架构,正常我们写的代码一般都是MVC架构的。以简单的登录界面为例:
public class MainActivity extends AppCompatActivity {
private TextView tv_result;
private EditText et_input;
private Button btn_login;
//进度条
ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_result = findViewById(R.id.tv_result);
et_input = findViewById(R.id.et_input);
btn_login = findViewById(R.id.btn_login);
// 初始化进度条
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getData(et_input.getText().toString().trim());
}
});
}
/**
* 模拟网络请求
* @param input
*/
public void getData(final String input) {
progressDialog.show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
switch (input) {
case "success":
tv_result.setText("登录成功");
break;
case "fail":
tv_result.setText("请求失败:参数有误");
break;
case "error":
tv_result.setText("请求报错: 500");
break;
}
progressDialog.dismiss();
}
},1000);
}
}
我们可以看到,UI处理、业务逻辑、数据请求都在一起,当页面逻辑越复杂时,我们activity中代码越多,后面迭代维护时越麻烦,当有逻辑相似的页面时,我们还要重新写一遍,造成代码冗余,复用性差,这就需要用到我们的MVP架构,下面我们将代码进行优化:
先新建网络请求的响应
public interface IBaseCallback{
/**
* 数据请求成功
* @param data 请求结果
*/
void onSuccess(String data);
/**
* 网络请求成功,但数据请求失败(如参数错误,数据解析报错,后台报错等)
* @param msg 错误原因
*/
void onFailure(String msg);
/**
* 网络请求失败
* @param error 失败原因
*/
void onError(String error);
/**
* 当请求数据结束时,无论结果如何,都会走的方法,一般用于加载框显示隐藏控制
*/
void onComplete();
}
将网络请求单独封装成model
public class MvpModel {
/**
* 获取网络接口数据
* @param param 请求参数
* @param callback 数据回调接口
*/
public static void getNetData(final String param, final IBaseCallback<String> callback){
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
switch (param){
case "success":
callback.onSuccess("登录成功");
break;
case "fail":
callback.onFailure("请求失败:参数有误");
break;
case "error":
callback.onError("请求报错: 500");
break;
}
callback.onComplete();
}
},1000);
}
}
创建Presenter进行业务逻辑处理
public class MvpPresenter {
private MvpView mvpView;
/**
* 获取绑定的mvpView
*/
public MvpView getMvpView() {
return mvpView;
}
/**
* 绑定view,一般在初始化中调用该方法,为避免网络请求后view被销
* 毁造成空指针,所以将presenter与view绑定
*/
public void attachView(MvpView mvpView) {
this.mvpView = mvpView;
}
/**
* 断开view,一般在onDestroy中调用
*/
public void detachView() {
this.mvpView = null;
}
/**
* 检测是否与View建立连接,避免view被销毁后空指针
* 每次调用业务请求的时候都要出先调用方法检查是否与View建立连接
*/
public boolean isViewAttached() {
return mvpView != null;
}
public void getData(String params) {
getMvpView().showLoading();
MvpModel.getNetData(params, new IBaseCallback<String>() {
@Override
public void onSuccess(String data) {
if (isViewAttached())
getMvpView().showData(data);
}
@Override
public void onFailure(String msg) {
if (isViewAttached())
getMvpView().showFailureMessage(msg);
}
@Override
public void onError(String error) {
if (isViewAttached())
getMvpView().showErrorMessage(error);
}
@Override
public void onComplete() {
if (isViewAttached())
getMvpView().hideLoading();
}
});
}
}
新建view的接口,然后用activity实现
public interface MvpView {
/**
* 当数据请求成功后,调用此接口显示数据
*/
void showData(String data);
/**
* 当网络请求成功,但有其他报错时后,调用此接口提示
*/
void showFailureMessage(String msg);
/**
* 当网络请求失败,调用此接口提示
*/
void showErrorMessage(String error);
/**
* 显示正在加载进度框
*/
void showLoading();
/**
* 隐藏正在加载进度框
*/
void hideLoading();
}
public class MainActivity extends AppCompatActivity implements MvpView{
private TextView tv_result;
private EditText et_input;
private Button btn_login;
MvpPresenter mvpPresenter;
//进度条
ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_result = findViewById(R.id.tv_result);
et_input = findViewById(R.id.et_input);
btn_login = findViewById(R.id.btn_login);
// 初始化进度条
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
mvpPresenter = new MvpPresenter();
mvpPresenter.attachView(this);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mvpPresenter.getData(et_input.getText().toString().trim());
}
});
}
@Override
public void showData(String data) {
tv_result.setText(data);
}
@Override
public void showFailureMessage(String msg) {
tv_result.setText(msg);
}
@Override
public void showErrorMessage(String error) {
tv_result.setText(error);
}
@Override
public void showLoading() {
if (!progressDialog.isShowing()){
progressDialog.show();
}
}
@Override
public void hideLoading() {
if (progressDialog.isShowing()){
progressDialog.dismiss();
}
}
}
这样就将我们平常写的MVC架构的代码,改为了MVP的,后面还可以将presenter抽取基类,view抽取基类,将代码更简化
网友评论