美文网首页
从零开始搭建MVP架构

从零开始搭建MVP架构

作者: CoolKin | 来源:发表于2021-08-04 15:10 被阅读0次

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抽取基类,将代码更简化

相关文章

网友评论

      本文标题:从零开始搭建MVP架构

      本文链接:https://www.haomeiwen.com/subject/ueayvltx.html