MVP框架搭建

     说到MVP,在网上查找了很多相关的资料,基本上是看得时候模模糊糊,然后过段时间就忘记了,如今空闲下来就来简单记录一下这个MVP吧。

网上都喜欢拿着MVP和MVC之间比较,然后就会有两张图,我反正是第一次看到时候是懵逼的,就像背书一样记下来(全是为了面试),后来随着代码量的增加,然后逐渐对这些有了新的认识,网上再多东西都是别人的,只有当自己理解了才是属于自己的。

    基本都是这两张图,然而没什么卵用,对于MVC这个模式,就是基本没有啥思想,高兴就好,基本业务逻辑全在Activity(Fragment)这样写多了问题自然也就出现了,一个页面代码量巨长,然后某一天让你去改两个月前的一个页面中的某一个点的时候,突然发现,找都要找一会,这样就蛋疼了,而且发现很多相同的东西每个页面都要写一下,很明显的就是相同的网络请求,这样也很不爽,页面多了,同样的网络请求就会在好多个页面都会写一遍,因此我觉得应该引入MVP了,我对于MVP的理解不太向上面那个图一样,总而言之,高兴就好。

Activity 和Fragment 视为View层,负责处理 UI。Presenter 为业务处理层,既能调用UI逻辑,又能请求数据,该层为纯Java类,不涉及任何Android API。Model 层中包含着具体的数据请求,数据源。

三层之间调用顺序为View->Presenter->Model,那么问题就来了,我的处理是,那么Presenter和Model之间怎么连接起来的呢?我选择的是CallBack,View和Presenter之间我用的就是iView,iView这个东西就是基本MVP的标配了,这个CallBack就自己脑袋想想,实际上跟iView是差不多的东西,详情请看下面讲解

Callback

将信息从Model反馈给Presenter,这里写的是网络请求的反馈。在实际情况中可根据项目情况修改

public interface Callback<T> {
    /**
     * 数据请求成功
     *
     * @param data 请求到的数据
     */
    void onSuccess(T data);

    /**
     * 使用网络API接口请求方式时,虽然已经请求成功但是由
     * 于msg的原因无法正常返回数据。
     */
    void onFailure(String msg);

    /**
     * 请求数据失败,指在请求网络API接口请求方式时,出现无法联网、
     * 缺少权限,内存泄露等原因导致无法连接到请求数据源。
     */
    void onError();

    /**
     * 当请求数据结束时,无论请求结果是成功,失败或是抛出异常都会执行此方法给用户做处理,通常做网络
     * 请求时可以在此处隐藏“正在加载”的等待控件
     */
    void onComplete();
}

Model

这里就可以写我们请求网络的接口方法,我下面是利用postDelayed来模拟的数据请求。然后通过callback将数据丢出去。

public class MvpModel  {
    /**
     * 获取网络接口数据
     * @param param 请求参数
     * @param callback 数据回调接口
     */
    public static void getNetData(final String param, final MvpCallback<String> callback){
        // 利用postDelayed方法模拟网络请求数据的耗时操作
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                switch (param){
                    case "normal":
                        callback.onSuccess(param+"参数请求成功了");
                        break;
                    case "failure":
                        callback.onFailure("请求失败");
                        break;
                    case "error":
                        callback.onError();
                        break;
                }
                callback.onComplete();
            }
        },1800);
    }
}

Presenter

具体的业务逻辑类,根据网络请求的反馈进行处理,这里通过iView反馈给View(Activity/Fragment),下面我也用到了isViewAttach()方法,就是处理异步网络请求反馈回来数据,然后当前的页面消失掉了的处理,防止崩溃。然后需要View展示的各种结果也是在这里通过iView进行分发处理。

public class MvpPresenter extends BasePresenter<MvpView> {
    /**
     * 获取网络数据
     *
     * @param params 参数
     */
    public void getData(String params) {
        if (!isViewAttached()) {
            //如果没有View引用就不加载数据
            return;
        }
        //显示正在加载进度条
        getView().showLoading();
        // 调用Model请求数据
        MvpModel.getNetData(params, new MvpCallback<String>() {
            @Override
            public void onSuccess(String data) {
                //调用view接口显示数据
                if (isViewAttached()) {
                    getView().showData(data);
                }
            }

            @Override
            public void onFailure(String msg) {
                //调用view接口提示失败信息
                if (isViewAttached()) {
                    getView().showToast(msg);
                }
            }

            @Override
            public void onError() {
                //调用view接口提示请求异常
                if (isViewAttached()) {
                    getView().showErr();
                }
            }

            @Override
            public void onComplete() {
                // 隐藏正在加载进度条
                if (isViewAttached()) {
                    getView().hideLoading();
                }
            }
        });
    }
}

iView

也就是定义一些方法,需要presenter反馈回来的方法,在View中接收然后处理,下面粘出来base的处理,不同的View的处理就各自继承然后自己定义。

public interface IBaseView {
    /**
     * 显示正在加载view
     */
    void showLoading();
    /**
     * 关闭正在加载view
     */
    void hideLoading();
    /**
     * 显示提示
     * @param msg
     */
    void showToast(String msg);
    /**
     * 显示请求错误提示
     */
    void showErr();

}

Actiivty这下就省事多了,接收Presenter的反馈,然进行调用。唯一要注意的是添加View的引用和断开View的引用,一个在OnCreate(),一个在OnDestory()中。

public class MainActivity extends BaseActivity implements MvpView, View.OnClickListener {
    private TextView tv_text;
    MvpPresenter presenter;
    private TextView tv_normal;
    private TextView tv_failure;
    private TextView tv_error;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_text = findViewById(R.id.tv_text);
        tv_normal= findViewById(R.id.tv_normal);
        tv_normal.setOnClickListener(this);
        tv_failure=findViewById(R.id.tv_failure);
        tv_failure.setOnClickListener(this);
        tv_error=findViewById(R.id.tv_error);
        tv_error.setOnClickListener(this);
        //初始化Presenter
        presenter = new MvpPresenter();
        presenter.attachView(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //断开View引用
        presenter.detachView();
    }

    @Override
    public void showData(String data) {
        tv_text.setText(data);
    }

    public void getData(View view) {
        presenter.getData("normal");
    }

    public void getDataForFailure(View view) {
        presenter.getData("failure");
    }

    public void getDataForError(View view) {
        presenter.getData("error");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.tv_normal:
                getData(tv_normal);
                break;
            case R.id.tv_failure:
                getDataForFailure(tv_failure);
                break;
            case R.id.tv_error:
                getDataForError(tv_error);
                break;
        }
    }
}

好了一个完整的MVP就这么结束了。

猜你喜欢

转载自blog.csdn.net/greatdaocaoren/article/details/84836165