一、概述
随着Okhttp使用越来越普遍,他的方便之处也被人熟知,本章简单介绍一下okhttp的使用过程:
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();
}
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
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();
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;
}
}
参考文章