Android开发知识

Android的MVP架构实践

2018-12-06  本文已影响0人  Crazyerick

最近研读了许多关于Android架构的分享资料,同时查阅了Android官方MVP架构案例的源码,获益良多,在这以一个简单的Demo谈谈我对MVP架构理解,以及和传统MVC架构的对比。

一、需求

二、方案

MVC
//Controller层+View层
public class MVCActivity extends AppCompatActivity {
    private Button mMvcBtn;
    private TextView mMvcTv;
    private MVCModel model;

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

        mMvcBtn = findViewById(R.id.btn_mvc);
        mMvcTv = findViewById(R.id.tv_mvc);
        model = new MVCModel();
        mMvcBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // OnClickListener是属于view的,这里View直接访问了model
                model.getData(new Callback1<String>() {
                    @Override
                    public void onCallback(String s) {
                        updateText(s);
                    }
                });
            }
        });
    }

    //该方法属于Controller
    private void updateText(final String text) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mMvcTv.setText(text);
            }
        });
    }
}


//Model层
public class MVCModel implements BaseModel {
    public void getData(final Callback1<String> callback1) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                    //模拟网络请求
                    String msg = "来自网络的数据: " + new Random().nextInt(100);
                    callback1.onCallback(msg);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
MVP
  1. View和Presenter之间的接口契约类:MVPContract.java
public interface MVPContract {

    interface IMVPModel extends BaseModel {
        void getData(Callback1<String> callback);
    }

    interface IMVPView extends BaseView<IMVPPresenter> {
        void updateText(String text);
        void showToast(String msg);
    }

    interface IMVPPresenter extends BasePresenter<IMVPView> {
        void request();
    }
}
  1. View层:MVPActivity.java
public class MVPActivity extends BaseActivity<MVPContract.IMVPView, MVPContract.IMVPPresenter> implements MVPContract.IMVPView {
    private Button mMvpBtn;
    private TextView mMvpTv;

    @Override
    protected void initUI(Bundle savedInstanceState) {
        setContentView(R.layout.activity_mvp);
        mMvpBtn = findViewById(R.id.btn_mvp);
        mMvpTv = findViewById(R.id.tv_mvp);
        mMvpBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mPresenter != null) {
                    //这里将用户请求转发给Presenter
                    mPresenter.request();
                }
            }
        });
    }
    ...

    @Override
    protected MVPContract.IMVPPresenter createPresenter() {
        return new MVPPresenter();
    }

    @Override
    public void setPresenter(MVPContract.IMVPPresenter presenter) {
        mPresenter = presenter;
    }

    @Override
    public void updateText(final String text) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mMvpTv.setText(text);
            }
        });
    }

    @Override
    public void showToast(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }
}
public abstract class BaseActivity<V extends BaseView, P extends BasePresenter<V>> extends AppCompatActivity {
    protected P mPresenter;

    @SuppressWarnings("unchecked")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = createPresenter();
        mPresenter.attachView((V) this);
        initUI(savedInstanceState);
        initParams();
        initData();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mPresenter != null) {
            mPresenter.onSaveInstanceState(outState);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mPresenter != null) {
            mPresenter.onStart();
        }
    }

    @Override
    protected void onDestroy() {
        if (mPresenter != null) {
            mPresenter.onDestroy();
        }
        super.onDestroy();
    }

    protected abstract P createPresenter();
    protected abstract void initUI(Bundle savedInstanceState);
    protected abstract void initParams();
    protected abstract void initData();
}
  1. Presenter层:MVPPresenter.java
public class MVPPresenter extends AbstractPresenter<MVPContract.IMVPView, MVPContract.IMVPModel> implements MVPContract.IMVPPresenter {

    @Override
    protected MVPContract.IMVPModel createModel() {
        return new MVPModel();
    }

    @Override
    public void request() {
        if (model != null) {
            //这里请求Model层拉取数据
            model.getData(new Callback1<String>() {
                @Override
                public void onCallback(String s) {
                    if (isViewAttached()) {
                        getView().updateText(s);
                    }
                }
            });
        }
    }
}

public interface BasePresenter<V extends BaseView> {
    void onStart();
    void onDestroy();
    void onSaveInstanceState(Bundle outState);
    void attachView(V view);
    void detachView();
}
public abstract class AbstractPresenter<V extends BaseView, M extends BaseModel> implements BasePresenter<V> {
    protected WeakReference<V> viewRef;
    protected M model;

    public AbstractPresenter() {
        model = createModel();
    }

    @Override
    public void onStart() {
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
    }

    @Override
    public void onDestroy() {
        detachView();
        model.onDestroy();
    }

    @Override
    public void attachView(V v) {
        viewRef = new WeakReference<V>(v);
        viewRef.get().setPresenter(this);
    }

    @Override
    public void detachView() {
        if (viewRef != null) {
            viewRef.clear();
            viewRef = null;
        }
    }

    public void setModel(M m) {
        model = m;
    }

    protected V getView() {
        return viewRef == null ? null : viewRef.get();
    }

    protected boolean isViewAttached() {
        return viewRef != null && viewRef.get() != null;
    }

    protected abstract M createModel();
}
  1. Model层:MVPModel.java
//这里的Model层实现和MVC中的没有任何差别
public class MVPModel implements MVPContract.IMVPModel {
    @Override
    public void getData(final Callback1<String> callback) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                    //模拟从网络拉取数据
                    String msg = "来自网络的数据: " + new Random().nextInt(100);
                    callback.onCallback(msg);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

三、对比

架构 开发速度 难度 低耦合 流行度 可测性 代码复用
MVC 5星 1星 2星 1星 2星 1星
MVP 4星 3星 4星 4星 4星 4星

四、总结

上一篇下一篇

猜你喜欢

热点阅读