欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android MVP简单实现

程序员文章站 2022-05-12 20:25:39
...
  1. MVC:Model-View-Controller,经典模式,很容易理解,主要缺点有两个:
    1、View对Model的依赖,会导致View也包含了业务逻辑;
    2、Controller会变得很厚很复杂。

    M --> Model(存放数据模型)
    V --> View(存放activity 和一些自定义的View)
    C --> Cotroller(业务逻辑处理)
    
  2. 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 模式。

Android MVP简单实现

Activity 和Fragment 视为View层,负责处理 UI。

Presenter 为业务处理层,既能调用UI逻辑,又能请求数据,该层为纯Java类,不涉及任何Android API。

Model 层中包含着具体的数据请求,数据源。

三层之间调用顺序为view->presenter->model。

具体实例:

Android MVP简单实现

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);
    }
}

MVPdemo下载

相关标签: android mvp