概述
- Retrofit本身是没有缓存的,如果想设置缓存功能,需要在http client层知道HTTP的语义。
- okhttp是square公司发布的一个HTTP client,它支持高速缓存服务器响应的语义。
- 使用场景:提高用户体验,降低服务器的负荷。无网络的条件下,读取缓存;有网条件下,对非实时性的数据可以在规定的时间里读取缓存,例如设置时间为60s,实时性的数据还是要每次都获取最新数据。
封装Retrofit管理类
public class RetrofitManger {
private static RetrofitManger mInstance;
public static boolean isDebug = false;
public static synchronized RetrofitManger getInstance() {
if (mInstance == null)
mInstance = new RetrofitManger();
return mInstance;
}
public void deBug(boolean isDebug) {
this.isDebug = isDebug;
}
// create retrofit singleton
private Retrofit createApiClient(String baseUrl) {
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(createOkHttpClient(isDebug))
.build();
}
// create okHttpClient singleton
OkHttpClient createOkHttpClient(boolean debug) {
//设置缓存100M
Cache cache = new Cache(new File(MainApplication.getContext().getCacheDir(),"httpCache"),1024 * 1024 * 100);
return new OkHttpClient.Builder()
.cache(cache)
.addNetworkInterceptor(new HttpCacheInterceptor())
.addInterceptor(
new HttpLoggingInterceptor().setLevel(
debug ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE))
.build();
}
}
HttpCacheInterceptor类
public class HttpCacheInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!NetWorkHelper.isNetConnected(MainApplication.getContext())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (NetWorkHelper.isNetConnected(MainApplication.getContext())) {
int maxAge = 60; // read from cache for 1 minute
response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
return response;
}
}
有网络的情况下设置max-age=60,即1分钟;没有网络的情况下设置max-stale=60 x 60 x 24 x 28,即4周。
okhttp3 中Cache类包含的缓存策略
noCache :不使用缓存,全部走网络
noStore : 不使用缓存,也不存储缓存
onlyIfCached : 只使用缓存
maxAge :设置最大失效时间,失效则不使用
maxStale :设置最大失效时间,失效则不使用
minFresh :设置最小有效时间,失效则不使用
FORCE_NETWORK : 强制走网络
FORCE_CACHE :强制走缓存
单个接口设置缓存
上面介绍的都是统一设置缓存,Retrofit还可以为单个接口设置缓存。
配置单个请求的@Headers,设置此请求的缓存策略不影响其他请求的缓存策略,不设置则没有缓存。
// 设置单个请求的缓存时间
@Headers("Cache-Control: max-age=640000")
@GET("user/list")
Call<List<javaBean>> getList();
读取单个接口的@Headers配置
String cacheControl = request.cacheControl().toString();
response.newBuilder()
.header("Cache-Control", cacheControl)
.removeHeader("Pragma")
.build();