zoukankan      html  css  js  c++  java
  • OKHttp3 简介与使用

    一、简介

    Android系统提供了两种HTTP通信类:HttpURLConnection和HttpClient,前者对比后者十分难用。
    网络请求进化:HttpURLConnection --- Apache HttpClient --- Volley ---OKHttp
    volley是google官方提供的网络请求框架,它依赖于httpclient,而在Android6.0的sdk中去掉了httpclient,因而okhttp更受欢迎。
    从Android4.4开始HttpURLConnection的底层实现采用的是okHttp 

    二、特点

    • 一般的get请求
    • 一般的post请求
    • 基于Http的文件上传
    • 文件下载
    • 加载图片
    • 支持请求回调,直接返回对象、对象集合
    • 支持session的保持
    • 支持自签名网站https的访问,提供方法设置下证书就行
    • 支持取消某个请求

    三、OKHTTP的基本使用

    1 引入依赖
    compile 'com.squareup.okhttp3:okhttp:3.7.0'
    2 使用前,认识一下核心类
    • OKHttpClient 客户端对象
    • Request是OKHttp中的请求,post请求中需要包含RequestBody
    • Build是辅助类,用于生产对象
    • Response是OKHttp中的响应,响应中可以得到返回是否成功,返回数据
    • RequestBody请求数据,在Post请求中用到
    • client.newCall(request).execute()同步请求
    • client.newCall(request).enqueue(CallBack callback)异步请求,但是CallBack里面的代码实在子线程执行的,因此不能更新UI。需要配合Handle使用,更新UI。
    3 基本使用步骤

    3.1 创建OKHttpClient对象,官方推荐单例。

    3.2 创建Request对象,这个对象是请求对象,需要指定URL。

           如果是post请求,需要通过FormEncodingBuilder创建RequestBody对象,指定post传进去的参数。get不需要。

    3.3 调用okhttpClient的newCall(request).enqueue(CallBack callback)或者execute方法。在callback的回调onResonse函数里做你需要做的事情。onResponse在子线程执行,如需更新UI,配合handler使用。

          enqueue是异步请求,有回调接口,execute是同步请求,没有回调接口。一般使用异步请求。

    四、基础封装

    public class OKHttpHelper {
    
        private static OKHttpHelper mHelper = null;
        private static OkHttpClient mClient = null;
        private Handler mHandler;
    
        /**
         * 私有构造函数
         */
        private OKHttpHelper() {
    //      没有响应时使用超时结束call。没有响应的原因可能是客户点链接问题、服务器可用性问题或者这之间的其他东西。
            mClient = new OkHttpClient().newBuilder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(10, TimeUnit.SECONDS).build();
            mHandler = new Handler(Looper.getMainLooper());
        }
    
        /**
         * 单例模式 获取实例
         *
         * @return
         */
        public static OKHttpHelper getInstance() {
            if (mHelper == null) {
                synchronized (OKHttpHelper.class) {
                    if (mHelper == null) {
                        mHelper = new OKHttpHelper();
                    }
                }
            }
            return mHelper;
        }
    
        /**
         * 对外公开的post方法
         * <p>
         * post请求需要通过FormEncodingBuilder创建RequestBody对象,指定post传进去的参数
         *
         * @param url      请求地址
         * @param params   请求参数
         * @param callBack 回调接口
         * @param tag      请求标签
         */
        public void post(String url, Map<String, String> params, BaseCallBack callBack, int tag) throws Exception {
            Request req = buildRequest(url, params, tag);
            request(req, callBack);
        }
    
        /**
         * 对外公开的get方法
         *
         * @param url
         * @param callBack
         */
        public void get(String url, BaseCallBack callBack, int tag) throws Exception {
            Request req = buildRequest(url, null, tag);
            request(req, callBack);
        }
    
        /**
         * 构建request请求对象
         *
         * @param url
         * @param params
         * @return
         */
        private Request buildRequest(String url, Map<String, String> params, int tag) {
            Request.Builder builder = new Request.Builder();
            builder.url(url);//请求地址
            if (null == params) {
                builder.get();//get请求
            } else {
                builder.post(buildRequestBody(params));//post请求 添加参数
            }
            builder.tag(tag);//tag 区分不同的请求
            return builder.build();
        }
    
        /**
         * 通过Map的键值对 构建post请求的RequestBody对象
         *
         * @param params
         * @return
         */
        private RequestBody buildRequestBody(Map<String, String> params) {
            FormBody.Builder formEncodingBuilder = new FormBody.Builder();
            if (params != null) {
                for (Map.Entry<String, String> entity : params.entrySet()) {
                    formEncodingBuilder.add(entity.getKey(), entity.getValue());
                }
            }
            return formEncodingBuilder.build();
        }
    
    
        /**
         * 接口请求 post,get请求通用
         *
         * @param request  请求对象
         * @param callBack 回调接口
         */
        private void request(final Request request, final BaseCallBack callBack) throws Exception {
            callBack.onRequestBefore();
            mClient.newCall(request).enqueue(new Callback() {//异步访问网络
                @Override
                public void onFailure(Call call, final IOException exception) {
                    if (!call.isCanceled()) {//请求未取消
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                //请求失败 网络异常
                                callBack.onFailure(exception);
                            }
                        });
                    }
                }
    
                @Override
                public void onResponse(Call call, final Response response) throws IOException {
                    if (!call.isCanceled()) {//链接超时 或者其他原因 导致请求取消
                        if (response.isSuccessful()) {
                            String res = response.body().string();
                            mHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    callBack.onSuccess(response, (Integer) response.request().tag());
                                }
                            });
                        } else {
                            mHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    //请求成功 获取数据异常
                                    callBack.onError(response, response.code(), null);
                                }
                            });
                        }
                    }
                }
            });
        }
    }
    

    回调接口

    public abstract class BaseCallBack<T> {
    
        /**
         * 请求之前调用
         */
        public abstract void onRequestBefore();
    
        /**
         * 请求失败(网络问题)
         * @param e
         */
        public abstract void onFailure(Exception e);
    
        /**
         * 请求成功
         * @param response
         * @param tag
         */
        public abstract void onSuccess(Response response, int tag);
    
        /**
         * 请求成功但是有错误(接口错误,数据解析错误等)
         * @param response
         * @param errorCode
         * @param e
         */
        public abstract void onError(Response response,int errorCode,Exception e);
    
    }
    

    补充:

    OKHttp 源码:http://blog.csdn.net/u012124438/article/details/54236967

    AsyncHttpClient : 基于HTTPClient的异步请求框架 http://www.it165.net/pro/html/201406/16421.html

    xutils : http://doc.okbase.net/u010870518/archive/125128.html

  • 相关阅读:
    C#命名约定:PascalCase和camelCase
    Windows8 App 四大名著完整本 隐私保护声明
    C#-编码习惯
    [转]C#之Console.Write()和Console.Read()及Console.Readline()的问题
    通过JavaScript动态输入计算
    在VS2008中加入ExtJS智能提示—>(方法一)
    在VS2008中加入ExtJS智能提示—>(方法二)
    (一)javascript面向对象:(1)类
    上证指数波浪分析2013/03/12
    Springsecurity源码Filter之HeaderWriterFilter(十二)
  • 原文地址:https://www.cnblogs.com/suiyilaile/p/5276772.html
Copyright © 2011-2022 走看看