一、什么是拦截器?
拦截器是一种能够监控,重写,重试调用的强大机制。我们可以使用拦截器添加我们的头信息,网络请求,网络缓存等。
二、拦截器的分类:(两大类):
1、应用拦截器(Application Interceptors)
2、网络拦截器(NetWork Interceptors)
Application interceptors应用程序拦截器
- 不需要担心比如重定向和重试的中间响应。
- 总是被调用一次,即使HTTP响应结果是从缓存中获取的。
- 监控应用程序的原始意图。不关心例如OkHttp注入的头部字段If-None-Match。
- 允许短路,不调用Chain.proceed()。
- 允许重试并多次调用Chain.proceed()。
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor()).build();
Request request = new Request.Builder()
.url("http://www.publicobject.com/helloworld.txt")
.header("User-Agent", "OkHttp Example")
.build();
Response response = client.newCall(request).execute();
response.body().close();
Network Interceptors网络拦截器
- 能够对中间的响应进行操作比如重定向和重试。
- 当发生网络短路时,不调用缓存的响应结果。
- 监控数据,就像数据再网络上传输一样。
- 访问承载请求的连接Connection。
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(new LoggingInterceptor())
.build();
Request request = new Request.Builder()
.url("http://www.publicobject.com/helloworld.txt")
.header("User-Agent", "OkHttp Example") .build();
Response response = client.newCall(request).execute();
response.body().close();
自定义网络拦截器:
Interceptor interceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
String cacheControl = request.cacheControl().toString();
if (TextUtils.isEmpty(cacheControl)) {
cacheControl = "public, max-age=60";
}
return response.newBuilder()
.header("Cache-Control", cacheControl)
.removeHeader("Pragma")
.build();
}
};
设置client:
//设置缓存路径
File httpCacheDirectory = new File(mContext.getCacheDir(), "responses");
//设置缓存 10M
Cache cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024);
//创建OkHttpClient,并添加拦截器和缓存代码
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(interceptor)
.cache(cache)
.build();
FORCE_NETWORK常量是用来使用网络请求。FORCE_CACHE只取本地的缓存。不同于拦截器设置缓存,CacheControl是针对Request的,所以它可以针对每个请求设置不同的缓存策略。
//缓存文件夹
File cacheFile = new File(getExternalCacheDir().toString(),"cache");
//缓存大小为10M
int cacheSize = 10 * 1024 * 1024;
//创建缓存对象
final Cache cache = new Cache(cacheFile,cacheSize);
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
//设置缓存时间为60秒
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(60, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.url(URL)
.cacheControl(cacheControl)
.build();
强制使用缓存:CacheControl.FORCE_CACHE这个常量
public static final CacheControl FORCE_CACHE = new Builder()
.onlyIfCached()
.maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.url(URL)
.cacheControl(Cache.FORCE_CACHE)
.build();
不使用缓存:CacheControl.FORCE_NETWORK这个常量(第一种方案)
public static final CacheControl FORCE_NETWORK = new Builder().noCache().build();
Request request = new Request.Builder()
.url(URL)
.cacheControl(Cache.FORCE_NETWORK)
.build();
不使用缓存:将maxAge设置为0,也会直接访问网络(第二种方案)
Request request = new Request.Builder()
.url(URL)
.cacheControl(new CacheControl.Builder()
.maxAge(0, TimeUnit.SECONDS))
.build();
Okhttp3设置缓存:
OkHttpClient okHttpClient = new OkHttpClient();
OkHttpClient newClient = okHttpClient.newBuilder()
.cache(new Cache(mContext.getCacheDir(), 10*1240*1024))
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.build();