okHttp使用及优缺点

前言

今天在这里要讲的是一个网络库,okHttp相对于其它网络库有很多不同,使用、效率、拦截器都有很多不同,当然也有坏处,比如callback回来

是在线程里面, 不能刷新UI,访问请求跟apache有很多不同,这点注意,还有访问请求的时候,Get和Post有不同就是看一个地方,如果是用其它

网络库,一定会迷惑到底那个才是Get\POST,文章中会细细解答,本文会以介绍、使用、优缺点来三大块阐述。

一、介绍

OKHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟,

还有透明的GZIP压缩,请求缓存等优势,其核心主要有路由、连接协议、拦截器、代理、安全性认证、连接池以

及网络适配,拦截器主要是添加,移除或者转换请求或者回应的头部信息,总流程图如下:

当然详细了解核心解刨内核东西网址如:

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0326/2643.html等。

二、使用

1.okhttp初始化

 Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
     @Override public Response intercept(Chain chain) throws IOException {
         Response originalResponse = chain.proceed(chain.request());
         return originalResponse.newBuilder()
                 .removeHeader("Pragma")
                 .header("Cache-Control", String.format("max-age=%d", 60))
                 .build();
     }
 };

 mOkHttpClient.setConnectTimeout(15000, TimeUnit.SECONDS);
 mOkHttpClient.setReadTimeout(15000, TimeUnit.SECONDS);
 mOkHttpClient.setWriteTimeout(15000, TimeUnit.SECONDS);
 mOkHttpClient.setRetryOnConnectionFailure(true);
 //-------------------------------设置http缓存,提升用户体验-----------------------------------
 Cache cache;
 File httpCacheDirectory =  StorageUtils.getOwnCacheDirectory(context,HTTP_CACHE_FILENAME);
 cache = new Cache(httpCacheDirectory, 10 * 1024);
 mOkHttpClient.setCache(cache);
 mOkHttpClient.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR);
 //-------------------------------设置http缓存,提升用户体验-----------------------------------

// Handler mDelivery = new Handler(Looper.getMainLooper());

 if (false) {
     mOkHttpClient.setHostnameVerifier(new HostnameVerifier() {
         @Override
         public boolean verify(String hostname, SSLSession session) {
             return true;
         }
     });
 }


2.Get申请数据

Request request = new Request.Builder()
        .url("网络地址这里面设置一个传参数如何办")
        .addHeader("Accept", "application/json; q=0.5").build();
上面代码看到url缺么有带post,这就是get,我当时看到这个半天还在想这就是Get,至少带get的字样,缺么有,这就是Get,然后这
里面涉及的一个参数如何传。会有两个问题参数如何传、如果是apache的,如何转到okhttps,后面都会在我的github会封装一个库。
<span style="white-space:pre">	</span>FormEncodingBuilder body = new FormEncodingBuilder();
        for (ConcurrentHashMap.Entry<String, String> entry : params.urlParams.entrySet()) {
            body.addEncoded(entry.getKey(), entry.getValue());
        }
        Request request = new Request.Builder()
                .url(getUrlWithQueryString(true, params.url, params))
                .build();
        try {
            BaseOkHandler handler = new BaseOkHandler(callback, params);
            client.newCall(request).enqueue(handler);
        } catch (Exception e) {
            e.printStackTrace();
        }
上面看到的params就相当于apache中的RequestParams类,里面传入参数就可以,借鉴的并做修改后得到。
 getUrlWithQueryString(boolean shouldEncodeUrl, String url, BaseParams params) {
        if (url == null)
            return null;

        if (shouldEncodeUrl) {
            try {
                String decodedURL = URLDecoder.decode(url, "UTF-8");
                URL _url = new URL(decodedURL);
                URI _uri = new URI(_url.getProtocol(), _url.getUserInfo(), _url.getHost(), _url.getPort(), _url.getPath(),
 _url.getQuery(), _url.getRef());
                url = _uri.toASCIIString();
            } catch (Exception ex) {
                // Should not really happen, added just for sake of validity
            }
        }

        if (params != null) {
            // Construct the query string and trim it, in case it
            // includes any excessive white spaces.
            String paramString = params.getParamString().trim();
            // Only add the query string if it isn't empty and it
            // isn't equal to '?'.
            if (!paramString.equals("") && !paramString.equals("?")) {
                url += url.contains("?") ? "&" : "?";
                url += paramString;
            }
        }

        return url;
    }
而这个函数就是把所有参数格式化拼接成一个字符串。

3.Post申请数据

 Request request = new Request.Builder()
      .url(url)
      .post(body)//post是关键,提交表单数据、这里面有封装好多库。
      .build();
      Response response = client.newCall(request).execute();

4.Post提交文件

 MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);
        if (params.fileParams.size() > 0) {
            RequestBody fileBody = null;
       for (ConcurrentHashMap.Entry<String, BaseParams.FileWrapper> entry1 : params.fileParams.entrySet()) {
                {
                    File file = entry1.getValue().file;
                    String fileName = file.getName();
                    fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileName)), file);
                    //TODO 根据文件名设置contentType
                    builder.addPart(Headers.of("Content-Disposition",
                                "form-data; name=\"" + entry1.getKey() + "\"; filename=\"" + fileName + "\""),
                            fileBody);
                }
            }
        }
        Request request = new Request.Builder()
                .url(params.url)
                .post(builder.build())
                .build();
大家 看到上传文件只要使用MultipartBuilder类表单传入就可以。

5.消息回来处理

public class BaseOkHandler implements Callback {

    private HttpCallback callBack;
    BaseParams param;

    public BaseOkHandler(HttpCallback response, BaseParams cacheParams) {
        this.callBack = response;
        param = cacheParams;
    }

    @Override
    public void onFailure(Request request, IOException e) {
    }

    @Override
    public void onResponse(Response response) throws IOException {
        try {
            if (response.isSuccessful()) {
                //成功得到文本信息
                String content = response.body().string();
                //通过Handler来传给UI线程。
                Message msg =new Message();
                msg.obj = content;
                msg.what=0;
                mHandler.sendMessage(msg);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    //得到数据并去做解析类。
     BaseEntity entity = JsonPaserFactory.paserObj(msg.obj.toString(), param.paserType);
                    //通知UI界面
    callBack.onSuccess(msg.obj.toString(), entity, param.paserType);
                    break;
                default:
                    break;
            }
        }

    };
}

三、优缺点

1、优点
支持SPDY, 可以合并多个到同一个主机的请,使用连接池技术减少请求的延迟(如果SPDY是可用的话) ,
使用GZIP压缩减少 传输 的数据量, 缓存响应避免重复的网络请求、拦截器等等。
2、缺点
第一缺点是消息回来需要切到主线程,主线程要自己去写,第二传入调用比较复杂。

四、封装okhttp

地址https://github.com/apple317?tab=repositories. 当前1.1版本已经开放完毕。
后续博客跟进:





发布了50 篇原创文章 · 获赞 7 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/Apple_hsp/article/details/50964923