对Xutils3的联网进行封装

来源:互联网 发布:众银家苹果下载软件 编辑:程序博客网 时间:2024/06/06 12:28

本文为原创,转载请写明出处,[原文链接](http://blog.csdn.net/qq_33737742)

1,先描述一下需求

目前正在用的http请求是Xutils,现在发现使用OkHttp来封装一套会更好。又比方说,目前正在用的数据存储方案是OrmLite,现在使用greenDao或者Realm会更好,在类似这些情况下,如何做到不修改Activity/Fragment/Presenter代码的情况下,把Volley的http请求实现更换成Okhttp的实现,把OrmLite更换成greenDao或者Realm?

解决问题的关键词:设计模式中的——工厂方法模式。下面我说一下我的思路


1.把Xutils中的http请求框架的共性方法抽取到接口中,我们把这个接口称为“请求接口”;2.创建一个用于返回请求结果的接口,我们把这个接口称为“回调接口”;3.分别用Volley和OkHttp实现“请求接口”;4.创建一个类来返回上述接口的对象,我们把这个类叫做“工厂”类;5.在Activity/Fragment/Presenter中,使用“工厂”返回的这个接口对象调用get/post/put/delete方法,并在“回调接口”中得到请求结果。

直接上代码

1.把共性方法抽取到接口中

/*** Created by lvfeifei on 2016/12/11.*/public interface IRequestManager {<T> Callback.Cancelable get(String url, Map<String, String> map, Callback.CommonCallback<T> callback);<T> Callback.Cancelable post(String url, Map<String, Object> map, Callback.CommonCallback<T> callback);<T> Callback.Cancelable UpLoadFile(String url, Map<String, Object> map, Callback.CommonCallback<T> callback);<T> Callback.Cancelable DownLoadFile(String url, String filepath, Callback.CommonCallback<T> callback);

}

2.用Xutils的联网请求类XUtilsRequestManager实现这个接口,我这里写了四个方法

/** * Created by 吕飞飞 on 2016/12/23. * 用于封装XUtils联网和上传下载文件 */public class XUtilsRequestManager implements IRequestManager {    public static XUtilsRequestManager getInstance() {    return SingletonHolder.INSTANCE;    }    private static class SingletonHolder {        private static final XUtilsRequestManager INSTANCE = new XUtilsRequestManager();    }/** * 发送get请求 * * @param <T> */@Overridepublic  <T> Callback.Cancelable get(String url, Map<String, String> map, Callback.CommonCallback<T> callback) {    RequestParams params = new RequestParams(url);    params.setConnectTimeout(5000);    if (null != map) {        for (Map.Entry<String, String> entry : map.entrySet()) {            params.addQueryStringParameter(entry.getKey(), entry.getValue());        }    }    Callback.Cancelable cancelable = x.http().get(params, callback);    return cancelable;}/** * 发送post请求 * * @param <T> */@Overridepublic <T> Callback.Cancelable post(String url, Map<String, Object> map, Callback.CommonCallback<T> callback) {    RequestParams params = new RequestParams(url);    if (null != map) {        for (Map.Entry<String, Object> entry : map.entrySet()) {            params.addParameter(entry.getKey(), entry.getValue());        }    }    Callback.Cancelable cancelable = x.http().post(params, callback);    return cancelable;}/** * 上传文件 * * @param <T> */@Overridepublic <T> Callback.Cancelable UpLoadFile(String url, Map<String, Object> map, Callback.CommonCallback<T> callback) {    RequestParams params = new RequestParams(url);    if (null != map) {        for (Map.Entry<String, Object> entry : map.entrySet()) {            params.addParameter(entry.getKey(), entry.getValue());        }    }    params.setMultipart(true);    Callback.Cancelable cancelable = x.http().get(params, callback);    return cancelable;}/** * 下载文件 * * @param <T> */@Overridepublic <T> Callback.Cancelable DownLoadFile(String url, String filepath, Callback.CommonCallback<T> callback) {    RequestParams params = new RequestParams(url);// 设置断点续传    params.setAutoResume(true);    params.setSaveFilePath(filepath);    Callback.Cancelable cancelable = x.http().get(params, callback);    return cancelable;}public class JsonResponseParser implements ResponseParser {    // 检查服务器返回的响应头信息    @Override    public void checkResponse(UriRequest request) throws Throwable {    }    /**     * 转换result为resultType类型的对象     *     * @param resultType     *            返回值类型(可能带有泛型信息)     * @param resultClass     *            返回值类型     * @param result     *            字符串数据     * @return     * @throws Throwable     */    @Override    public Object parse(Type resultType, Class<?> resultClass, String result) throws Throwable {        return new Gson().fromJson(result, resultClass);        }    }}

3.创建一个类来返回IRequestManager请求接口的对象

/** * Created by lvfeifie on 2016/12/11. */public class RequestFactory {    public static IRequestManager getRequestManager(){//        return VolleyRequestManager.getInstance();        return XUtilsRequestManager.getInstance();    }}

为什么要用这种方法来返回对象,而不直接在Activity/Fragment/Presenter中创建>VolleyRequestManager对象来进行操作?

如果直接在Activity/Fragment/Presenter中使用VolleyRequestManager来创建对象,你的代码就依赖了VolleyRequestManager,这种情况下,如果要更换成OkHttp,岂不是要把代码中所有的VolleyRequestManager对象也更换成OkHttp的请求对象?

再试想一下,如果你有很多个Activity/Fragment/Presenter使用了VolleyRequestManager对象,你是不是要每个地方都更换一遍?

使用RequestFactory的方式在Activity/Fragment/Presenter中创建对象,代码只依赖了IRequestManager这个接口,这就是使用接口进行解耦的关键点,无论在什么地方使用了这个接口,当要更换实现的时候,只需要修改RequestFactory中return的实现类就可以了。

4.用法

 //这里发起请求依赖的是IRequestManager接口    URL = "www.baidu.com"    IRequestManager requestManager = RequestFactory.getRequestManager();    Map<String, Object> mapPost = null;    requestManager.post(URL, mapPost, new Callback.CommonCallback<String>() {        @Override        public void onSuccess(String result) {            if(result != null) {                // 保存首页数据                //this.result=result;                CacheUtils.putString(PersonalInformationActivity.this, CacheUtils.USER_INFORMATION,result);                Log.e("Login中的result,更换成功",result);                prosessDate(result);            }        }        @Override        public void onError(Throwable ex, boolean isOnCallback) {        }        @Override        public void onCancelled(CancelledException cex) {        }        @Override        public void onFinished() {        }    });

注意我们创建请求对象的代码,这里没有出现具体的实现类: IRequestManager requestManager = RequestFactory.getRequestManager();

5.想换就换

只要换的联网方法实现了第三步中的方法就行RequestFactory

1 0
原创粉丝点击