Android当中的MVP模式(五)封装之后的OkHttp工具在Model层
来源:互联网 发布:java要学到什么程度 编辑:程序博客网 时间:2024/06/06 04:53
个人博客:CODE FRAMER BIGZ
MVP系列文章配套DEMO
Android 当中的 MVP 模式(一)基本概念
Android 当中的 MVP 模式(二)封装
Android 当中的 MVP 模式(三)基于分页列表的封装
Android 当中的 MVP 模式(四)插曲-封装 OkHttp
Android 当中的 MVP 模式(五)封装之后的 OkHttp 工具在 Model 层的使用
Android 当中的 MVP 模式(六)View 层 Activity 的基类— BaseMvpActivity 的封装
Android 当中的 MVP 模式(七)终篇—关于对 MVP 模式中代码臃肿问题的思考
摘要:在上一篇中对 OkHttp
进行了简单的封装,但是没有使用到这个系列当中的 Demo
里面,这一章就使用上一篇封装的 OkHttp
工具,替换掉之前 Demo
里面的 Model
层的网络请求.并且之前的部分接口方法都没有使用,比如说 IBasePresenter
接口中的 HashMap<String, String> getParams()
方法, IBasePaginationPresenter
中的 boolean hasMoreData()
方法,算是对上一篇的补充。
Model 层原来的写法
拿分页数据获取的 Model
层举例,当时在 SohuAlbumModel
中是这样获取数据的:
@Override public void sendRequestToServer(Param param) { String validUrl = null; Log.d(TAG, ">> sendRequestToServer >> " + "has more data ?" + mPaginationPresenter.hasMoreData()); if (param != null && !TextUtils.isEmpty(url) && mPaginationPresenter.hasMoreData()) { validUrl = getValidUrl(url, param); Log.d(TAG, ">> sendRequestToServer >> " + "ValidUrl:" + validUrl); } if (!TextUtils.isEmpty(validUrl)) { HttpUtils.executeByGet(validUrl, new Callback() { @Override public void onFailure(Call call, IOException e) { Log.d(TAG, ">> onFailure >> "); e.printStackTrace(); mPaginationPresenter.okHttpError(Constants.URL_ERROR, e.getMessage(), url); } @Override public void onResponse(Call call, Response response) throws IOException { if (!response.isSuccessful()) { Log.d(TAG, ">> onResponse >> " + "Not successful"); mPaginationPresenter.okHttpError(Constants.SERVER_ERROR, response.message(), url); } String responseJson = response.body().string(); Log.d(TAG, ">> onResponse >> " + "responseJson:" + responseJson); mPaginationPresenter.accessSuccess(responseJson); } }); } else { Log.d(TAG, ">> sendRequestToServer >> " + "Valid Url is empty"); } } private String getValidUrl(String url, Param param) { return String.format(url, param.getPageIndex(), param.getPageSize()); }
url
当中的参数是直接在 sendRequestToServer
方法中传递进来的,这么一来会让 Model
层的职责变得不那么单一,因为 Model
层只应该负责数据相关的工作,此处的 params
传递进来,还需要进行一个 url
的拼接工作,所以在这里是可以优化的地方。
在看看上一篇中的 OkHttpManager
类中请求服务器数据的核心方法:
/** * 使用{@link OkHttpClient}想服务器端请求数据的方法 * @param method {@link Constants#HTTP_GET_METHOD} Get方式,{@link Constants#HTTP_POST_METHOD} Post方式 * @param baseUrl baseUrl * @param paramsMap 请求url的参数,以键值对的形式存放 * @param handler */ public void requestServerData(int method, String baseUrl, HashMap<String, String> paramsMap, DisposeDataHandler handler) { RequestParams requestParams = new RequestParams(paramsMap); Request request = null; if (method == Constants.HTTP_GET_METHOD) { request = CommonRequest.createGetRequest(baseUrl, requestParams); } else if (method == Constants.HTTP_POST_METHOD) { request = CommonRequest.createPostRequest(baseUrl, requestParams); } if (request != null) { mOkHttpClient.newCall(request).enqueue(new CommonJsonCallback(handler)); } }
使用 OkHttpManager
来请求服务器获得数据,第二个参数 HashMap<String, String> paramsMap
就是已经在 Presenter
层中处理好的键值对参数,然后在 CommonRequest.createGetRequest(baseUrl, requestParams);
或者是 CommonRequest.createPostRequest(baseUrl, requestParams)
中就已经把完整的 url
拼接出来了。具体如何拼接,如何构造 Request
对象,Model
层完全不用关心,它只需要在请求成功或者是请求失败的回调接口中将数据回调到 Presenter
层去即可。
那么现在就开始重构 Model
层的方法。
Model 层现在的写法
@Override public void sendRequestToServer() { if (mPaginationPresenter.hasMoreData()) { OkHttpManager.getInstance().requestServerData(method, baseUrl, mPaginationPresenter.getParams(), new DisposeDataHandler(new DisposeDataListener() { @Override public void onSuccess(Object responseObj) { String responseJson = (String) responseObj; Log.d(TAG, ">> onSuccess >> " + responseJson); mPaginationPresenter.accessSuccess(responseJson); } @Override public void onFailure(OkHttpException exception) { Log.d(TAG, ">> onFailure >> " + exception.getErrorCode()); mPaginationPresenter.okHttpError(exception.getErrorCode(), exception.getErrorMsg(), url); } }, null)); }else { Log.d(TAG,">> sendRequestToServer >> " + "No more data!"); } }
是不是简单了很多!和之前的方法相比较,有三处不同的地方:
- 第
2
行的sendRequestToServer()
方法中已经没有了param
参数了。(那么参数从哪儿来呢?) - 第
3
行多了一个hasMoreData()
的方法,用于判断服务器端还有没有更多的数据。若没有,那就没有必要去请求了。它是在哪儿初始化的? - 第
4
行的多了mPaginationPresenter.getParams()
,它是在什么地方初始化的? - 第
4
行的baseurl
不是之前Model
层的url
下面就解释为什么可以这么操作。
BasePaginationPresenter 的修改
观察之前 Model
层的写法就知道,这个地方的参数,主要是从其中取出 pageIndex
和 pageSize
,用于拼接新的 url
,然后再请求数据,这儿不需要这个参数了, 那肯定就是有地方已经提供了这个参数了咯。 对,就是 mPaginationPresenter.getParams()
这个之前没有用过的方法,先回顾一下这个方法在哪儿定义的:
public interface IBasePresenter<Param> { //省略部分代码 /** * 在Model层中调用,此方法用于获取Presenter层处理好的参数 * @author zfy * @return 请求参数 * @Created at 2017/10/21/021 15:05 */ HashMap<String, String> getParams(); }
在第二篇中,针对每一层封装的时候,这个接口就已经定义好了,只是一直没有使用上,在这儿就用上了。而 BasePaginationPresenter
类是实现这个街口的,并且这个 Presenter
是分页请求数据中 Presenter
层的基类,在第三篇也提到过。下面看看 BasePaginationPresenter
:
/** * @author:ZengFanyu * @date:2017/10/20 */ public abstract class BasePaginationPresenter<Param extends BasePaginationParam, Data> implements IBasePaginationPresenter<Param> { //省略部分代码 /** * 子类实现,用于确认服务器端是否还有数据 * * @return true-还有数据 false-没有数据 */ public abstract boolean serverHaveMoreData(); /** * 子类实现,用于返回请求服务器的url当中的参数 * * @return HashMap<String,String> url 中的 kay value 对 */ public abstract HashMap<String, String> getHttpRequestParams(); //省略部分代码 @Override public HashMap<String, String> getParams() { return getHttpRequestParams(); } @Override public boolean hasMoreData() { return serverHaveMoreData(); } }
只贴出和之前不同的部分,
- 多了一个
serverHaveMoreData()
抽象方法,子类去实现的,用于判断服务器还有没有更多的数据。 - 多了以个
getHttpRequestParams()
抽象方法,子类去实现,用于将参数填充到HashMap
中,供Model
层使用。
接下里看看子类 AlbumPresenter
的实现:
AlbumPresenter 的修改
/** * @author:ZengFanyu * Function: */ public class AlbumPresenter extends BasePaginationPresenter<BasePaginationParam, Album> { private int mTotalCount=-1; public AlbumPresenter(BaseMvpActivity baseListView, Class<Album> aClass) { super(baseListView, aClass); this.mBaseListView = baseListView; getModel().setRequestMethod(Constants.HTTP_GET_METHOD); getModel().setRequestUrl(Constants.SOHU_SERIALS_URL_BASE); } //省略代码 @Override public void serverResponse(Album album) { //省略代码 mTotalCount = album.getData().getCount(); } @Override public boolean serverHaveMoreData() { //此处pageIndex是从1开始的, 实际适用需要注意pageIndex的起始值 int pageSize = mParam.getPageSize(); int pageIndex = mParam.getPageIndex(); //第一次需要返回true 才能进到 serverResponse 方法中去初始化 mTotalCount 值 return mTotalCount == -1 || (pageIndex * pageSize) <= mTotalCount; } @Override public HashMap<String, String> getHttpRequestParams() { HashMap<String, String> paramsMap = new HashMap<>(); paramsMap.put("cid", "2"); paramsMap.put("o", "1"); paramsMap.put("plat", "6"); paramsMap.put("poid", "1"); paramsMap.put("api_key", "9854b2afa779e1a6bff1962447a09dbd"); paramsMap.put("sver", "6.2.0"); paramsMap.put("sysver", "4.4.2"); paramsMap.put("partner", "47"); paramsMap.put("page", String.valueOf(mParam.getPageIndex())); paramsMap.put("page_size", String.valueOf(mParam.getPageSize())); return paramsMap; } }
与之前实现不同地方在于:
- 构造方法当中设置的
url
,现在是baseUrl
,后面的参数由getHttpRequestParams
方法生成,在CommonRequest
中生成完整url
。 serverResponse()
方法中,对mTotalCount
进行了初始化, 这个值就是记录服务器端一共有多少条数据的。serverHaveMoreData()
拿当前已经加载的数据条数和mTotalCount
进行对比,判断是否还有数据。getHttpRequestParams()
构造参数的HashMap
。
小结
从这一章的从重构部分代码,很明显可以看到,各层之间的依赖关系:
- 主要是替换网络请求的工具,那么就是只涉及到
Model
层的改动。 - 这里
Presenter
层改动了,其实是不需要改动的, 这里改动了的原因是,我把之前没有实现的功能补上了,并且将sendRequestToServer()
的参数去掉了导致的。 - 可以发现,
View
层代码没有进行一点修改,也就是Activity
并没有动。
个人博客地址 :CODER FRAMER BIGZ
- Android当中的MVP模式(五)封装之后的OkHttp工具在Model层
- Android当中的MVP模式(四)插曲-封装OkHttp
- Android当中的MVP模式(六)View 层 Activity 的基类--- BaseMvpActivity 的封装
- Android 当中的 MVP 模式(二)封装
- Android当中的MVP模式(三)基于分页列表的封装
- MVP模式+OKhttp的封装请求数据
- mvp封装的OKhttp
- Android当中的MVP模式(一)基本概念
- 基于OKhttp的MVP封装
- Android:网络层的封装(使用OkHttp)
- Android当中的MVP模式(七)终篇---关于对MVP模式中代码臃肿
- Android Okhttp工具类的封装
- RxJava+okhttp+Retrofit+Mvp 的封装
- MVP 模式(Model-View-Presenter)可以说是 MVC 模式(Model-View-Controller)在 Android 开发上的一种变种、进化模式。
- Android OkHttp的封装
- Android——MVP架构OkHttp的二次封装以及RecyclerView的使用
- Android OKHttp的高度封装
- ym——Android开发MVP模式(解决了View和Model的耦合)
- Android当中的MVP模式(四)插曲-封装OkHttp
- Hibernate入门(三)
- resnet-avgpooling 踩的坑 python 调试 debug+多处设置断点 及 枚举:enumerate()
- 【py-faster-rcnn】【训练自己数据】需要修改的参数小记
- 每日练习2017-11-02
- Android当中的MVP模式(五)封装之后的OkHttp工具在Model层
- XML与数据库
- 采用jsp来实现一个轮播图
- Android当中的MVP模式(六)View 层 Activity 的基类--- BaseMvpActivity 的封装
- Java4Android笔记之Java中继承初步
- Effective Java
- Java中字符串的操作
- Spark学习之(一) HDFS 集群环境搭建
- 网络设备驱动代码