通俗易懂的MVP架构讲解

MVP结构图。

核心思路:切断的View和Model的联系,让View只和Presenter(原Controller)交互,减少在需求变化中需要维护的对象的数量。
1. 各部分之间的通信,都是双向的。
2. View 与 Model 不发生联系,都通过 Presenter 传递。
3. View 非常薄,不部署任何业务逻辑,称为”被动视图”(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。

1、MVP结构图

 

 

2、定义Model层的接口IModel

/**
* Model层接口---实现该接口的类负责实际的获取数据操作,如数据库读取、网络加载
*/
public interface IModel {

void getData(Model.LoadDataCallback callback);
}


然后创建Model实体类实现IModel接口,并覆写数据获取方法。

/**
 * 实现IModel接口,负责实际的数据获取操作(数据库读取,网络加载等),然后通过自己的接口(LoadDataCallback)反馈出去
 */
public class Model implements IModel {


    @Override
    public void getData(final LoadDataCallback callback) {
        //数据获取操作,如数据库查询、网络加载等
        new Thread() {
            @Override
            public void run() {
                try {
                    //模拟耗时操作
                    Thread.sleep(3000);
                    //获取到了数据
                    String data = "我是获取到的数据";
                    //将获取的数据通过接口反馈出去
                    callback.success(data);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //获取数据失败的回调
                    callback.failure();
                }
            }
        }.start();
    }

    public interface LoadDataCallback {

        void success(String taskId);

        void failure();
    }
}

 

2、定义IView接口

/**
 * View层接口---执行各种UI操作,定义的方法主要是给Presenter中来调用的
 */
public interface IView {

    void showLoadingProgress(String message);

    void showData(String text);
}

 

然后创建View实体类实现IView接口,并覆写UI操作方法。

 

/**
 * 实现IView接口并实现各种UI操作的方法(其他的业务逻辑在Presenter中进行操作)
 */
public class ViewActivity extends Activity implements IView {

    private Button mBtnShowToast;
    private TextView mText;
    private MyHandler mHandler = new MyHandler(ViewActivity.this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvp);

        mBtnShowToast = (Button) findViewById(R.id.btn_show_toast);
        mText = (TextView) findViewById(R.id.text);
        mBtnShowToast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
    }

    @Override
    public void showLoadingProgress(final String message) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mText.setText(message);
            }
        });
    }

    @Override
    public void showData(final String text) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mText.setText(text);
            }
        });
    }

    private class MyHandler extends Handler {

        //弱引用,防止内存泄露
        WeakReference<ViewActivity> weakReference;

        public MyHandler(ViewActivity activity) {
            this.weakReference = new WeakReference<ViewActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    weakReference.get().mText.setText(msg.what);
                    break;
            }
        }
    }
}

 

3、定义IPresenter接口

/**
 * Presenter层接口---控制Model层的数据操作及调用View层的UI操作来完成“中间人”工作
 */
public interface IPresenter {

    void loadData();

}


然后创建Presenter实体类实现IPresenter接口。

public class Presenter implements IPresenter, Model.LoadDataCallback {

    private final IView mView;
    private final Model mModel;

    public Presenter(IView view) {
        mView = view;
        mModel = new Model();
    }

    @Override
    public void loadData() {
        mView.showLoadingProgress("加载数据中");
        mModel.getData(Presenter.this);
    }

    @Override
    public void success(String data) {
        mView.showData(data);
    }

    @Override
    public void failure() {

    }
}

4、View中实例化Presenter,通过Presenter来处理业务逻辑。最终达到,View只负责UI操作,Model只负责数据,Presenter负责链接二者的目的。

View层完整代码

/**
 * 实现IView接口并实现各种UI操作的方法(其他的业务逻辑在Presenter中进行操作)
 */
public class ViewActivity extends Activity implements IView {

    private Button mBtnShowToast;
    private TextView mText;
    private MyHandler mHandler = new MyHandler(ViewActivity.this);
    private IPresenter mPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvp);

        //实例化Presenter,并将实现了IView接口的类传入进去
        mPresenter = new Presenter(ViewActivity.this);

        mBtnShowToast = (Button) findViewById(R.id.btn_show_toast);
        mText = (TextView) findViewById(R.id.text);
        mBtnShowToast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //通过Presenter来实现业务逻辑操作,View层只负责UI相关操作
                mPresenter.loadData();
            }
        });
    }

    @Override
    public void showLoadingProgress(final String message) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mText.setText(message);
            }
        });
    }

    @Override
    public void showData(final String text) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mText.setText(text);
            }
        });
    }

    private class MyHandler extends Handler {

        //弱引用,防止内存泄露
        WeakReference<ViewActivity> weakReference;

        public MyHandler(ViewActivity activity) {
            this.weakReference = new WeakReference<ViewActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    weakReference.get().mText.setText(msg.what);
                    break;
            }
        }
    }
}

大家要多看,多试验,最重要的是理解这个思路。Google官方的Todo MVP代码大家可以去研读一下,是同一个模式,只不过它把好多接口集成在一个接口文件中,防止代码碎片化,大家研读时记住这一点,就不会困惑了。

最后附上Google MVP的代码地址:

https://github.com/googlesamples/android-architecture/tree/todo-mvp/

原作者:

转载自:https://blog.csdn.net/limonzet/article/details/53328315 

posted @ 2019-05-29 16:37  小鱼2015  阅读(435)  评论(0)    收藏  举报