搭建自己的mvp项目

一.在看mvp之前我们首先应该了解android 中的三层架构

1.View层(直接展示给用户的)
2.业务逻辑层(桥接View层和数据访问层的,处理交互、业务逻辑)
3.数据访问层(对数据库操作)

二.传统的mvc

M-Model:对应用状态、业务功能的封装操作,接受Controller的调用完成业务处理,并发起通知更改View
V-View:界面展示,调用model的状态信息并显示
C-Controller:桥接m-v,View收集数据提供给Controller,Controller处理UI逻辑之后更改Model状态

三.mvp

在mvp中是禁止View和Model直接打交道的,需要沟通必须通过Presenter,这样Model/View被分隔开
在mvp中,v代表View抽象出来的的接口

下面一步一步打造自己的mvp

1.抽象一个自己的BasePresenter,上面提到Presenter是M-V沟通的桥梁,分割M-V用的,那么,就必须持有M-V code:

public abstract class BasePresenter<M, T> {
    protected M mModel;
    protected T mView;
    //初始化参数
    public void setViewAndModel(T v, M m) {
        this.mView = v;
        this.mModel = m;
    }

    /**
     * 解除M-V绑定操作
     */
    public void unBind(){
        if(null != mModel){
            mModel = null;
        }

        if(null != mView){
            mView = null;
        }
    }

2.有必要提供一个基类BaseView,BaseModel
BaseView.class

public interface BaseView {
    //显示进度
    void showLoading();
    //隐藏进度
    void hideLoading();
}

BaseModel.class

public interface BaseModel {
}

这里M-V-P就有骨架子了,下面需要把他们结合使用起来,需要构建一个约定,把三者结合
DemoContract.class

public interface DemoContract {
    interface DemoView extends BaseView {
        void refreshing();
    }

    interface DemoModel extends BaseModel {
        void setUserName(String name);
        void setUserSex(int sex);
    }

    abstract class Presenter extends BasePresenter<DemoModel, DemoView> {
        public abstract void login(String username, String password, String passcode);
    }

这里会发现Presenter里面传入的DemoModel,DemoView, DemoView就是我们刷新页面的接口,重点是DemoModel,这里的Model不是实体类(例如:服务器返回数据),而是我根据页面抽出来的一个对象,只用户页面展示
DemoModel.class

public class DemoModel implements DemoContract.DemoModel {

    private String userName;
    private int userSex;

    @Override
    public void setUserName(String name) {
        this.userName = name;
    }

    @Override
    public void setUserSex(int sex) {
        this.userSex = sex;
    }

    public String getUserName() {
        return userName;
    }

    public int getUserSex() {
        return userSex;
    }
}

定义DemoPresenter去继承约定里面的Presenter,用来处理业务逻辑
DemoPresenter.class

public class DemoPVPresenter extends DemoContract.Presenter{

    @Override
    public void login(String username, String password, String passcode) {
        mModel.setUserName(username);
        mModel.setUserSex(1);
        //调用视图刷新刷新
        mView.refreshing();
    }
}

到这里,我的mvp就构建完了,最重要的就是V层的使用了,首先定义一个DemoBaseActivity,需要我们传入P和M,作为约束
DemoBaseActivity.class

public abstract class DemoBaseActivity<T extends BasePresenter, E extends BaseModel> extends Activity {
    //继承类返回自己的xml文件名字,用于购建页面
    public abstract int initLayoutID();

    public abstract void handleOnCreated(Bundle savedInstanceState);

    //业务逻辑处理
    protected T mPresenter;
    //业务model
    protected E mModel;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        int layoutResID = initLayoutID();
        setContentView(layoutResID);

        handleOnCreated(savedInstanceState);

        mPresenter = MVPUtil.getT(this, 0);
        mModel = MVPUtil.getT(this, 1);
        if (this instanceof BaseView) {
            mPresenter.setViewAndModel(this, mModel);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        //解除绑定
        if (null != mPresenter) {
            mPresenter.unBind();
            mPresenter = null;
        }
    }
}

里面有一个泛型获取工具
MVPUtil.class

public class MVPUtil {
    public static <T> T getT(Object o, int i) {
        try {
            return ((Class<T>) ((ParameterizedType) (o.getClass()
                    .getGenericSuperclass())).getActualTypeArguments()[i])
                    .newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassCastException e) {
            e.printStackTrace();
        }
        return null;
    }
}

最后,就是使用了
DemoActivity.class

public class DemoActivity extends DemoBaseActivity<DemoPVPresenter,DemoModel> implements DemoContract.DemoView {

    TextView demoTv;
    Button demoBtn;

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }

    @Override
    public int initLayoutID() {
        return R.layout.activity_demo_layout;
    }


    @Override
    public void handleOnCreated(Bundle savedInstanceState) {
        demoTv = findViewById(R.id.demo_tv);
        demoBtn = findViewById(R.id.demo_btn);
        demoBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mPresenter.login("jiangHua","123456","100");
            }
        });
    }
    @Override
    public void refreshing() {
        demoTv.setText(new StringBuilder().append(mModel.getUserName()).append(mModel.getUserSex()).toString());
    }

这个是我自己弄的,有优化整改意见的,欢迎大家指出
github地址:https://github.com/otherface/Android-mvp

猜你喜欢

转载自blog.csdn.net/u013346208/article/details/80896193