前言 :

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 headerMap = new HashMap<>();        headerMap.put("phone", phonenumber);        final Map queryMap = new HashMap<>();        queryMap.put("key", "e8884c80009b02439019b4ee99c0d2a5");        Observable.create(new ObservableOnSubscribe() {            @Override            public void subscribe(ObservableEmitter e) throws Exception {                e.onNext(doGet(mUrl, headerMap, queryMap));                e.onComplete();            }        }).subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Observer() {                    @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 header, Map 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> headerIterator = header.entrySet().iterator();        headerIterator.forEachRemaining(new Consumer>() {            @Override            public void accept(Map.Entry e) {                urlBuilders.addQueryParameter(e.getKey(), String.valueOf(e.getValue()));            }        });        // 装载请求的参数        Iterator> queryIterator = query.entrySet().iterator();        queryIterator.forEachRemaining(new Consumer>() {            @Override            public void accept(Map.Entry 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是我们定义的View层的接口
public class QueryPhonePresenter extends MvpBasePresenter {    @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

public class MainActivity extends MvpActivity 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减少了一些不必要的代码,让代码逻辑看起来更加的清晰,易懂。

效果展示

 

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. ListView分页加载数据
  3. Android(安卓)SQLite 数据库详细介绍
  4. Android应用程序的开机自启动
  5. Android(安卓)实现自定义圆环
  6. android android 在list view中插入一条广告
  7. 跟Google学习Android开发-起始篇-保存数据(2)
  8. 分享这近做的一款android软件-"妞妞驾考"
  9. Android2018年最新前沿框架和技术

随机推荐

  1. android面试一些常见的问题
  2. Android横竖屏总结全
  3. android的binder机制研究(C++部分)
  4. 【Android(安卓)UI】ListView系列一(基础
  5. Android使用Cordova框架开发Android(安卓
  6. android资源引用
  7. Android实现高定制化日历控件
  8. Android(安卓)NFC 对sim卡读写注意事项
  9. Android虚拟机与Java虚拟机——两种虚拟
  10. android与html5的交互——数据库操作,UI操