• 超简单的okHttpUtils封装(下)


     

    版权声明:转载请注明出处:http://blog.csdn.net/piaomiao8179 https://blog.csdn.net/piaomiao8179/article/details/70888901

    前言:

    上一篇我们讲到了基本的Okhttp的封装,只需要我们在代码种调用okHttpUtils.getInstance().GET(url, MyCallBack),一句话完事,而且还是链式的,只需要在MyCallBack中处理返回的Response即可,是不是感觉很爽,不要着急,接下来会让你更爽,请自行准备纸巾,条件允许的话也可以为你的宝贝充上气。没有看过上篇文章的,最好看一下,点击即可跳转: 超简单的okhttp封装工具类(上)
    好了,废话不多说,进入正题,本篇主要思想是,通过上篇的封装,联网成功后,返回的是Response对象,我们平时联网需要的结果是一个JavaBean或者一个集合,泛型为JavaBean。那么,接下来就是实现直接返回带泛型的集合,而不是还需要我们处理的Response。

    MyCallBack接口的改写

    首先,在MyCallBack后面加上泛型,到时候需要实例化这个callback时候,自然的把我们需要转换成的JavaBean以泛型的形式传递过去。
    本篇采用Gson进行Response的json转换,所以需要根据泛型获取Type对象。获取方法如下:

    //根据T获取Type
    static Type getSuperclassTypeParameter(Class<?> subclass)
    {
        Type superclass = subclass.getGenericSuperclass();
        if (superclass instanceof Class)
        {
            throw new RuntimeException("Missing type parameter.");
        }
        ParameterizedType parameterized = (ParameterizedType) superclass;
        return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    我们原来定义的MyCallBack为接口,此时需要改写成抽象类,因为要用到构造方法进行构造Type对象。具体代码如下:

    public abstract class MyCallBack<T> {
    
    
    public  Type mType;
    
    static Type getSuperclassTypeParameter(Class<?> subclass)
    {
        Type superclass = subclass.getGenericSuperclass();
        if (superclass instanceof Class)
        {
            throw new RuntimeException("Missing type parameter.");
        }
        ParameterizedType parameterized = (ParameterizedType) superclass;
        return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
    }
    
    public MyCallBack() {
        mType = getSuperclassTypeParameter(getClass());
    }
    
    public abstract void onLoadingBefore(Request request);
    //第二个参数为传入的泛型,也就是说返回的结果直接就是我们需要的类型
    public abstract void onSuccess(Response response, T result);
    
    public abstract void onFailure(Request request, Exception e);
    
    public abstract void onError(Response response);
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    OkHttpUtils工具类的改写

    我们主要是改写Response返回的地方,也就是联网逻辑这一块,即requestNetWork()方法。具体请看代码实现,注释很清晰。

    private void requestNetWork(Request request, MyCallBack<Object> callBack) {
    
        /**
         * 处理连网逻辑,此处只处理异步操作enqueue
         */
        callBack.onLoadingBefore(request);
    
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                mHandler.post(() -> callBack.onFailure(request, e));
    
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
    
                    String resultStr = response.body().string();
                    if (callBack.mType == String.class) {
                        // 如果想要返回字符串 直接返回就行
                        mHandler.post(() -> callBack.onSuccess(response, resultStr));
                    } else {
                        // 需要返回解析好的javaBean集合
                        try {
                            // 此处暂时写成object,使用时返回具体的带泛型的集合
                            Object obj = mGson.fromJson(resultStr, callBack.mType);
                            mHandler.post(() -> callBack.onSuccess(response, obj));
                        } catch (Exception e) {
                            // 解析错误时
                            mHandler.post(() -> callBack.onError(response));
                        }
    
                    }
    
                } else {
                    mHandler.post(() -> callBack.onError(response));
                }
            }
        });
    
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    界面联网具体操作

    具体使用方法如下:在Fragment的OnCreatView方法中写的逻辑,根据需求自己选择在哪里联网,此处只是测试,不建议在这个方法中处理。会阻塞界面显示。

    private String url = "http://222.133.11.150:8402/EnvService/Version/CheckVersion?imei=860806029044186&version=111";
    
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
        OkHttpUtils.getInstance().Get(url, new MyCallBack<ceshiBean>() {
    
            @Override
            public void onLoadingBefore(Request request) {
    
            }
    
            @Override
            public void onSuccess(Response response, ceshiBean result) {
                System.out.println("-----" + result.getStrApkUrl());
            }
    
            @Override
            public void onFailure(Request request, Exception e) {
    
            }
    
            @Override
            public void onError(Response response) {
    
            }
        });
    
        return  inflater.inflate(R.layout.fragment_home,container,false);
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    ceshiBean的代码

    这是我们根据接口写的javaBean对象
    public class ceshiBean {

    /**
     * StrApkUrl : http://222.133.11.150:8402/EnvService/versioninfo/EnvDS_DZ.apk
     * StrUpdateDate : 2017.4.18
     * StrUpdateFlag : 0
     * StrUpdateLog :
     1.城市空气模块,新增加乡镇站、边界站、农村站交通站。
    
     * StrVersionCode : 110
     * StrVersionName : 1.1.0
     */
    
    private String StrApkUrl;
    private String StrUpdateDate;
    private String StrUpdateFlag;
    private String StrUpdateLog;
    private String StrVersionCode;
    private String StrVersionName;
    
    public String getStrApkUrl() {
        return StrApkUrl;
    }
    
    public void setStrApkUrl(String StrApkUrl) {
        this.StrApkUrl = StrApkUrl;
    }
    
    public String getStrUpdateDate() {
        return StrUpdateDate;
    }
    
    public void setStrUpdateDate(String StrUpdateDate) {
        this.StrUpdateDate = StrUpdateDate;
    }
    
    public String getStrUpdateFlag() {
        return StrUpdateFlag;
    }
    
    public void setStrUpdateFlag(String StrUpdateFlag) {
        this.StrUpdateFlag = StrUpdateFlag;
    }
    
    public String getStrUpdateLog() {
        return StrUpdateLog;
    }
    
    public void setStrUpdateLog(String StrUpdateLog) {
        this.StrUpdateLog = StrUpdateLog;
    }
    
    public String getStrVersionCode() {
        return StrVersionCode;
    }
    
    public void setStrVersionCode(String StrVersionCode) {
        this.StrVersionCode = StrVersionCode;
    }
    
    public String getStrVersionName() {
        return StrVersionName;
    }
    
    public void setStrVersionName(String StrVersionName) {
        this.StrVersionName = StrVersionName;
    }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    总结

    到此为止,已经实现了简化逻辑,只需要调用方法时候传入泛型javaBean即可,就能直接获取数据了。

    可能有的小伙伴会说,这只是单个javaBean对象的解析,如果我们接口返回的是好对个javaBean的集合,怎么办,so easy,只需要把泛型写成List的形式就好了,直接给你返回一个集合数据集,太爽了。

    当然,还有更方便的写法,你可以再次自定义一个具体的CallBack继承MyCallBack,实现里面的方法,在联网开始前显示加载对话框,解析结束隐藏对话框,处理相应的逻辑。那么在前台界面只需要处理你自己的数据就可以了。

    声明:本文实现思路是参考IVan的封装思路,只做学习用途。

    OkHttpUtils改进后的源码

    
    public class OkHttpUtils {
    
        /**
         * 网络访问要求singleton
         */
        private static OkHttpUtils instance;
    
        // 必须要用的okhttpclient实例,在构造器中实例化保证单一实例
        private OkHttpClient mOkHttpClient;
    
        public static final MediaType JSON = MediaType.
                parse("application/json; charset=utf-8");
    
        private Handler mHandler;
    
        private Gson mGson;
    
        private OkHttpUtils() {
            /**
             * okHttp3中超时方法移植到Builder中
             */
            mOkHttpClient = (new OkHttpClient()).newBuilder()
                        .connectTimeout(10, TimeUnit.SECONDS)
                        .readTimeout(10, TimeUnit.SECONDS)
                        .writeTimeout(30, TimeUnit.SECONDS)
                        .build();
    
            mHandler = new Handler(Looper.getMainLooper());
    
            mGson = new Gson();
        }
    
        public static OkHttpUtils getInstance() {
            if (instance == null) {
                synchronized (OkHttpUtils.class) {
                    if (instance == null) {
                        instance = new OkHttpUtils();
                    }
                }
            }
    
            return instance;
        }
    
        /**
         * 对外提供的Get方法访问
         * @param url
         * @param callBack
         */
        public void Get(String url, MyCallBack callBack) {
            /**
             * 通过url和GET方式构建Request
             */
            Request request = bulidRequestForGet(url);
            /**
             * 请求网络的逻辑
             */
            requestNetWork(request, callBack);
        }
    
        /**
         * 对外提供的Post方法访问
         * @param url
         * @param parms: 提交内容为表单数据
         * @param callBack
         */
        public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) {
            /**
             * 通过url和POST方式构建Request
             */
            Request request = bulidRequestForPostByForm(url, parms);
            /**
             * 请求网络的逻辑
             */
            requestNetWork(request, callBack);
    
        }
    
        /**
         * 对外提供的Post方法访问
         * @param url
         * @param json: 提交内容为json数据
         * @param callBack
         */
        public void PostWithJson(String url, String json, MyCallBack callBack) {
            /**
             * 通过url和POST方式构建Request
             */
            Request request = bulidRequestForPostByJson(url, json);
            /**
             * 请求网络的逻辑
             */
            requestNetWork(request, callBack);
    
        }
    
        /**
         * POST方式构建Request {json}
         * @param url
         * @param json
         * @return
         */
        private Request bulidRequestForPostByJson(String url, String json) {
            RequestBody body = RequestBody.create(JSON, json);
    
            return new Request.Builder()
                    .url(url)
                    .post(body)
                    .build();
        }
    
        /**
         * POST方式构建Request {Form}
         * @param url
         * @param parms
         * @return
         */
        private Request bulidRequestForPostByForm(String url, Map<String, String> parms) {
    
            FormBody.Builder builder = new FormBody.Builder();
    
            if (parms != null) {
                for (Map.Entry<String, String> entry :
                        parms.entrySet()) {
                    builder.add(entry.getKey(), entry.getValue());
                }
    
            }
            FormBody body = builder.build();
    
    
            return new Request.Builder()
                    .url(url)
                    .post(body)
                    .build();
        }
    
    
        /**
         * GET方式构建Request
         * @param url
         * @return
         */
        private Request bulidRequestForGet(String url) {
    
            return new Request.Builder()
                    .url(url)
                    .get()
                    .build();
        }
    
    
        private void requestNetWork(Request request, MyCallBack<Object> callBack) {
    
            /**
             * 处理连网逻辑,此处只处理异步操作enqueue
             */
            callBack.onLoadingBefore(request);
    
            mOkHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    mHandler.post(() -> callBack.onFailure(request, e));
    
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (response.isSuccessful()) {
    
                        String resultStr = response.body().string();
                        if (callBack.mType == String.class) {
                            // 如果想要返回字符串 直接返回就行
                            mHandler.post(() -> callBack.onSuccess(response, resultStr));
                        } else {
                            // 需要返回解析好的javaBean集合
                            try {
                                // 此处暂时写成object,使用时返回具体的带泛型的集合
                                Object obj = mGson.fromJson(resultStr, callBack.mType);
                                mHandler.post(() -> callBack.onSuccess(response, obj));
                            } catch (Exception e) {
                                // 解析错误时
                                mHandler.post(() -> callBack.onError(response));
                            }
    
                        }
    
                    } else {
                        mHandler.post(() -> callBack.onError(response));
                    }
                }
            });
    
    
        }
    
    
    }
    
  • 相关阅读:
    关于如何绑定Jquery 的scroll事件(兼容浏览器 Wookmark瀑布流插件)
    HttpHelper类使用方法
    Jquery实现弹出选择框选择后返回,支持多级分类
    让asp.net网站支持多语言,使用资源文件
    关于Android SDK Manager无法获取更新列表的正确设置
    Eclipse使用技巧总结
    配置java环境变量
    sqlserver游标使用和循环
    压缩SQLServer数据库日志的一个存储过程
    Jquery EasyUI封装简化操作
  • 原文地址:https://www.cnblogs.com/xgjblog/p/10578502.html
Copyright © 2020-2023  润新知