Android(安卓)Mosby MVP的使用
16lz
2021-01-26
前言 :
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
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减少了一些不必要的代码,让代码逻辑看起来更加的清晰,易懂。
效果展示
更多相关文章
- 一句话锁定MySQL数据占用元凶
- ListView分页加载数据
- Android(安卓)SQLite 数据库详细介绍
- Android应用程序的开机自启动
- Android(安卓)实现自定义圆环
- android android 在list view中插入一条广告
- 跟Google学习Android开发-起始篇-保存数据(2)
- 分享这近做的一款android软件-"妞妞驾考"
- Android2018年最新前沿框架和技术