您的位置:首页 > 理论基础 > 计算机网络

okHttp使用及优缺点

apple_hsp 2016-03-24 18:33 204 查看


前言

今天在这里要讲的是一个网络库,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版本已经开放完毕。
后续博客跟进:
标签: