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 层的写法就知道,这个地方的参数,主要是从其中取出 pageIndexpageSize ,用于拼接新的 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

阅读全文
0 0
原创粉丝点击