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

okhttp的详解及其缓存的使用

2017-03-22 15:49 260 查看
一、概述

随着Okhttp使用越来越普遍,他的方便之处也被人熟知,本章简单介绍一下okhttp的使用过程:

get请求

Post请求

文件的上传和下载

okhttp缓存的使用

平时使用可参照鸿洋大神封装的okhttpUtils点击前往

使用前准备:

Android Studio用户可以添加以下依赖:

compile 'com.squareup.okhttp:okhttp:2.4.0'


二、使用过程

- get请求:

OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("htttp://baidu.com").build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {

}

@Override
public void onResponse(Call call, Response response) throws IOException {
//TODO

}
});


根据上面代码看出okhttp的get请求一般步骤:

- 创建okhttpClient 对象

- 构建请求的Request(url()传入请求接口、build生成Request对象)

- 利用Request对象构建Call对象

- call.enqueue()加入调度队列,这里使用异步请求,另有excute()和cancel()。

- 在回调Callback中得到Response后,就可以根据需求获取返回结果如:response.body().string() 获取字符串; response.body().byteStream() 获取输入流; response.body().bytes()获取字节数组;

如果不采用异步请求上述代码可写成:

Request request = new Request.Builder().url("htttp://baidu.com").build();
try {
Response response = (new OkHttpClient().newCall(request)).execute();
} catch (IOException e) {
e.printStackTrace();
}


Post请求(携带参数请求)

OkHttpClient okHttpClient = new OkHttpClient();
FormBody formBody = new FormBody.Builder().add("KEY","Value").build();
Request request = new Request.Builder().url("htttp://baidu.com").post(formBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});


与get请求相比,Post的使用大致相同,只是request的构造形式不同,先构造Formbody传入要携带的参数用来构造RequestBody,利用Post()提交请求。

3. 文件的上传和下载

单个文件的上传

File file ;
if (!Environment.isExternalStorageRemovable() || Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
file = new File(getApplication().getExternalCacheDir(),"test.text");
else
file = new File (getApplication().getCacheDir(),"test.text");
RequestBody requestBody = RequestBody.create(MediaType.parse("text/x-markdown; charset=utf-8"),file);
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("htttp://baidu.com").post(requestBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}


Post分块上传,同时上传键值对和文件RequestBody构造如下:

RequestBody requestBody_all =  new MultipartBody.Builder().setType(MultipartBody.FORM).addPart(Headers.of("Content-Disposition",
"form-data; name=\"username\""),RequestBody.create(null,"Alex")).addPart(Headers.of("Content-Disposition","form-data;name=\"filename\""),requestBody).build();
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("htttp://baidu.com").post(requestBody_all).build();


请求之间的区别主要在于RequestBody之间的区别

文件的下载:

利用请求得到的response.body().byteStream() 得到输入流后,进行写入即可

三、 缓存

在App使用过程中,若信息没有任何改变而用户多次请求时,会造成流量的浪费和无意义的请求,尤其在一些数据不是经常变化的地方,使用缓存可以很好的提高用户体验和节省流量

1. 缓存策略

HTTP1.0使用的Expires过期策略,使用时间戳来判断是否过期,但是当客户端的时间和服务端时间不一致时会造成判断失误,HTTP1.1以上都采用Cache-control策略,此策略使用时间长度判断是否过期,即只根据两次请求之间的时间差判断是否有效,避免之前的问题,基本格式:

Cache-Control:max-age:+ 3600 * 24 * 30


缓存的原理

okhttp的缓存是通过拦截器intercept来实现的,添加拦截器:

new OkHttpClient.Builder().addInterceptor(new MyInterceptor);


okhttp内部定义一个ListInterceptor将每个添加的Interceptor 添加集合当中,最后遍历每个拦截器将每个请求体封装成Chain交给每个拦截器处理,在拦截器中修改请求头,使用Cache-control策略:

Response response1 = response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "max-age=" + 3600 * 24 * 30)
.build();


缓存的使用

服务器端支持缓存:

若服务器端支持缓存,请求返回的Response的头文件会带有Header:Cache-Control, max-age=xxx,此时只需要设置缓存的文件,一般采用Android推荐使用Context.getCacheDir()来作为缓存的存放路径,另外还需要指定缓存的大小就可以创建一个缓存了,okhttp会自动帮你缓存了:

OkHttpClient okHttpClient = new OkHttpClient.Builder().cache(getCache())
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20,TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.build();

public Cache getCache(){
return new Cache(mContext.getCacheDir(),1024*1024*10);
}


服务器端不支持缓存

此时需要创建Interceptor对象,修改请求返回的Response:

public class  MyInterceptor implements Interceptor{

@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
Response response1 = response.newBuilder().removeHeader("Pragma").removeHeader("Cache-Control")
.header("Cache-Control", "max-age=" + 3600 * 24 * 30).build();
return response1;
}
}


参考文章

泡网okhttp使用教程

Okhttp缓存解析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: