Android Mosby MVP的使用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_30996881/article/details/99411525

前言 :

Android Mvp 模式是现在常用的设计模式,将视图和业务逻辑解耦,分为Model-View-Presenter三个部分。

1.M 层 为数据模型 做一些数据相关的处理

2.P 层 控制View 层 为UI 交互的发起者 接受M层的反馈 然后对 View层的控制

3.V 层 接受P层的控制改变UI

今天我们要讲的是一个MVP的一个库 Mosby 他能更好的实现MVP,让实现MVP更加的快捷,方便更加清晰的搭建MVP。

开源地址:https://github.com/sockeqwe/mosby

官方介绍:http://hannesdorfmann.com/mosby/mvp/

依赖

  implementation 'com.hannesdorfmann.mosby:mvp:2.0.1'
  implementation 'com.hannesdorfmann.mosby:viewstate:2.0.1' 

程序实现

使用Mosby 编写一个应用程序,界面一个Button 一个EditView 一个TextView

  • 输入框输入电话号码
  • 点击按钮,请求接口查血电话号码的归属地
  • 显示电话号码的归属地

使用到的技术

  • Mosby
  • RxJava
  • OkHttp

1. Model 数据模型层

  定义从服务器返回的数据 Bean

Bean数据

   /**
     * resultcode : 200
     * reason : Return Successd!
     * result : {"province":"四川","city":"成都","areacode":"028","zip":"610000","company":"移动","card":""}
     * error_code : 0
     */

生成实体类,通过工具生成。

package com.hzy.phone.model;

public class PhoneInfo {

    /**
     * resultcode : 200
     * reason : Return Successd!
     * result : {"province":"四川","city":"成都","areacode":"028","zip":"610000","company":"移动","card":""}
     * error_code : 0
     */

    private int resultcode;
    private String reason;
    private ResultBean result;
    private int error_code;

    public int getResultcode() {
        return resultcode;
    }

    public void setResultcode(int resultcode) {
        this.resultcode = resultcode;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public ResultBean getResult() {
        return result;
    }

    public void setResult(ResultBean result) {
        this.result = result;
    }

    public int getError_code() {
        return error_code;
    }

    public void setError_code(int error_code) {
        this.error_code = error_code;
    }

    public static class ResultBean {
        /**
         * province : 四川
         * city : 成都
         * areacode : 028
         * zip : 610000
         * company : 移动
         * card :
         */

        private String province;
        private String city;
        private String areacode;
        private String zip;
        private String company;
        private String card;

        public String getProvince() {
            return province;
        }

        public void setProvince(String province) {
            this.province = province;
        }

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getAreacode() {
            return areacode;
        }

        public void setAreacode(String areacode) {
            this.areacode = areacode;
        }

        public String getZip() {
            return zip;
        }

        public void setZip(String zip) {
            this.zip = zip;
        }

        public String getCompany() {
            return company;
        }

        public void setCompany(String company) {
            this.company = company;
        }

        public String getCard() {
            return card;
        }

        public void setCard(String card) {
            this.card = card;
        }
    }
}

定义model层数据返回接口 成功 和  失败

public interface QueryModeListener {

    void onQuerySuccess(PhoneInfo phoneInfo);
    void onQueryError(int code);

}

编写Model层的数据请求实现,传入model的接口监听,回调成功和失败。通过RxJava 进行网络请求的线程切换。

 public static void queryPhoneNumber(String phonenumber, final QueryModeListener queryModeListener) {
        final Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("phone", phonenumber);
        final Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("key", "e8884c80009b02439019b4ee99c0d2a5");
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext(doGet(mUrl, headerMap, queryMap));
                e.onComplete();
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String s) {
                        Gson gson = new Gson();
                        PhoneInfo phoneInfo = gson.fromJson(s, PhoneInfo.class);
                        if (phoneInfo.getResultcode() == QUERY_SUCCESS) {
                            queryModeListener.onQuerySuccess(phoneInfo);
                        } else {
                            queryModeListener.onQueryError(phoneInfo.getError_code());
                        }
                        Log.e(TAG, "onNext: ");
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });
    }

请求数据的Okhttp,网络请求功能的实现

    private static String mUrl = "http://apis.juhe.cn/mobile/get?";
    private static String TAG = "QueryModel";
    private final static int QUERY_SUCCESS = 200;

     /**
     * get 请求
     *
     * @param url    url
     * @param header 请求头参数
     * @param query  参数
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    private static String doGet(String url, Map<String, Object> header, Map<String, Object> query) throws Exception {
        OkHttpClient client = new OkHttpClient();
        // 创建一个请求 Builder
        Request.Builder builder = new Request.Builder();
        // 创建一个 request
        Request request = builder.url(url).build();
        final HttpUrl.Builder urlBuilders = request.url().newBuilder();
        Iterator<Map.Entry<String, Object>> headerIterator = header.entrySet().iterator();

        headerIterator.forEachRemaining(new Consumer<Map.Entry<String, Object>>() {
            @Override
            public void accept(Map.Entry<String, Object> e) {
                urlBuilders.addQueryParameter(e.getKey(), String.valueOf(e.getValue()));
            }
        });

        // 装载请求的参数
        Iterator<Map.Entry<String, Object>> queryIterator = query.entrySet().iterator();
        queryIterator.forEachRemaining(new Consumer<Map.Entry<String, Object>>() {
            @Override
            public void accept(Map.Entry<String, Object> e) {
                urlBuilders.addQueryParameter(e.getKey(), (String) e.getValue());
            }
        });

        // 设置自定义的 builder
        builder.url(urlBuilders.build());
        try (Response execute = client.newCall(builder.build()).execute()) {
            return execute.body().string();
        }
    }

2.presenter 层的实现

P层主要思想为沟通M层和V层的数据交互和显示

QueryPhonePresenter 继承 MvpBasePresenter<QueryPhoneView> 注:QueryPhoneView是我们定义的View层的接口
public class QueryPhonePresenter extends MvpBasePresenter<QueryPhoneView> {

    @RequiresApi(api = Build.VERSION_CODES.N)
    public void queryPresenter(String phoneNuber) {
        QueryModeListener queryModeListener = new QueryModeListener() {
            @Override
            public void onQuerySuccess(PhoneInfo phoneInfo) {
                QueryPhoneView queryPhoneView = getView();
                if (queryPhoneView != null) {
                    queryPhoneView.onQuerySuccess(phoneInfo);
                }
            }

            @Override
            public void onQueryError(int code) {
                QueryPhoneView queryPhoneView = getView();
                if (queryPhoneView != null) {
                    queryPhoneView.onError(code);
                }
            }
        };
        QueryModel.queryPhoneNumber(phoneNuber, queryModeListener);
    }
}

实现model的接口,通过getView方法获取到View层的接口,然后进行View层的接口回调,实现改变View,最后调用Model的数据请求功能。

注:getView方法需要判null

3.View层的实现

定义View层的接口

public interface QueryPhoneView extends MvpView {

    void onQuerySuccess(PhoneInfo phoneInfo);
    void onError(int code);

}

最后Activity 继承 MvpActivity<QueryPhoneView, QueryPhonePresenter> 实现接口QueryPhoneView

public class MainActivity extends MvpActivity<QueryPhoneView, QueryPhonePresenter> implements QueryPhoneView, View.OnClickListener {

    private Button mQueryBt;
    private EditText mQueryEt;
    private TextView mQueryTv;
    private QueryPhonePresenter mQueryPhonePresenter;

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

    private void initView() {
        mQueryBt = findViewById(R.id.query_bt);
        mQueryEt = findViewById(R.id.nuber_et);
        mQueryTv = findViewById(R.id.dispaly_tv);
        mQueryBt.setOnClickListener(this);
    }

    @NonNull
    @Override
    public QueryPhonePresenter createPresenter() {
        if (mQueryPhonePresenter == null) {
            mQueryPhonePresenter = new QueryPhonePresenter();
        }
        return mQueryPhonePresenter;
    }

    @Override
    public void onQuerySuccess(PhoneInfo phoneInfo) {
        PhoneInfo.ResultBean resultBean = phoneInfo.getResult();
        mQueryTv.setText(resultBean.getCity());
    }

    @Override
    public void onError(int code) {
        mQueryTv.setText("ErrorCode" + code);
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onClick(View v) {
        mQueryPhonePresenter.queryPresenter(mQueryEt.getText().toString());
    }
}

重写方法createPresenter 从中获取到P层的实列。总体来说mosby减少了一些不必要的代码,让代码逻辑看起来更加的清晰,易懂。

效果展示

猜你喜欢

转载自blog.csdn.net/qq_30996881/article/details/99411525