从零到一搭建一个mvp框架

从零到一搭建一个mvp框架

本文旨在从零到一搭建一个mvp框架、对于mvp不了解的看这篇文章

正文开始

在里面新建两个接口(Interface),分别取名 BaseViewBaseModel,这里定义一些公共方法

public interface BaseView {
    
    void showLoading();
    
    void hideLoading();
    
    void showError();
    
}

public interface BaseModel {

}

接下来定义一个抽象类,取名 BasePresenter

public abstract class BasePresenter<M, V> {

    protected M mModel;
    //弱引用的写法,避免内存泄漏。
    protected WeakReference<V> mView;

    protected void onAttach(M m, V v) {
        mView = new WeakReference<>(v);
        mModel = m;
    }

    //检测 V 是否已关联 P
    protected boolean isViewAttached() {
        return null != mView && null != mView.get();
    }

    protected V getView() {
        return isViewAttached() ? mView.get() : null;
    }

    protected void onDetach() {
        if (null != mView) {
            mView.clear();
            mView = null;
        }
    }

}

该类则用于反射获取指定泛型

public class ReflectUtil {

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

}

接下来定义BaseActivity,举一反三BaseFragment同理

public abstract class BaseActivity<T extends BasePresenter, M extends BaseModel> extends AppCompatActivity implements BaseView {

    protected T mPresenter;
    protected M mModel;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutId());
        //通过反射获取presenter model对象
        mPresenter = ReflectUtil.getT(this, 0);
        mModel = ReflectUtil.getT(this, 1);
        //绑定
        mPresenter.onAttach(mModel, this);

        initView();
    }

    protected abstract int getLayoutId();

    protected abstract int initView();

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }

    @Override
    public void showError() {

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解绑
        mPresenter.onDetach();
    }
}

创建接口 MvpListener,用于数据从 M 到 V 的层间传递

public interface MvpListener<T> {
    void onSuccess(T result);

    void onError(String errorMsg);
}

接下来创建一个Contract,来归纳创建view、model、presenter接口,这里可以使用插件mvphelper,省去创建类的步骤

public interface MainContract {
    interface Model extends BaseModel {
        void loadDaily(String url, MvpListener<String> listener);
    }

    interface View extends BaseView {
        void setData(String s);
    }

    abstract class Presenter extends BasePresenter<Model, View> {
        abstract void loadData(String url);
    }
}

然后实现这三层,首先是presenter

public class MainPresenter extends MainContract.Presenter {
    @Override
    protected void loadData(String url) {
        MainContract.View mView = getView();
        if (mView == null) {
            return;
        }

        mView.showLoading();
        //调用model方法,获取网络请求回调结果
        mModel.loadDaily(url, new MvpListener<String>() {
            @Override
            public void onSuccess(String result) {
                mView.hideLoading();
                mView.setData(result);
            }

            @Override
            public void onError(String errorMsg) {
                mView.hideLoading();
                mView.showError();
            }
        });
    }
}

接下来是model,我这里网络请求使用的okgo,这个根据自己喜好用什么都一样,需要在成功跟失败的回调里去调用自定义的mvplistener

public class MainModel implements MainContract.Model {
    @Override
    public void loadDaily(String url, MvpListener<String> listener) {
        //这里执行网络请求操作
        OkGo.<String>get(url).execute(new StringCallback() {
            @Override
            public void onSuccess(Response<String> response) {
                listener.onSuccess(response.body());
            }

            @Override
            public void onError(Response<String> response) {
                super.onError(response);
                listener.onError(response.body());
            }
        });
    }
}

最后是view,也就是我们的activity

public class MainActivity extends BaseActivity<MainPresenter, MainModel> implements MainContract.View {

    private static final Locale LOCALE = Locale.CHINA;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    protected void initView() {
        mPresenter.loadData("http://news.at.zhihu.com/api/4/news/before/" + format(new Date(), "yyyyMMdd"));
    }


    @Override
    public void setData(String s) {
        Toast.makeText(this, "请求结果" + s, Toast.LENGTH_SHORT).show();
    }

    public static String format(Date date, String s) {
        return new SimpleDateFormat(s, LOCALE).format(date);
    }
}

本文意在搭建mvp,就不去做数据列表展示了,在这里做了一个toast,贴上成功的截图

 

最后,到这里mvp框架就搭建完毕了,总结一下实现过程

  • 创建baseview、basemodel、basepresenter、baseactivity基类
  • 创建contract类创建view、model、presenter内部类编写抽象方法
  • 创建view、model、presenter实现类

这里贴上我的demo,需要的可以下载参考一下 https://download.csdn.net/download/zyz18813049204/16303268

 

 

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值