我需要实现API响应的基本缓存。我做了一个小游乐场项目,调用GitHub API并且缓存成功(我已经使用Charles来验证)。但是,当我将此解决方案转移到我的目标项目时,缓存不再有效。链中的多个拦截器可能是原因吗?
游乐场项目代码(工作):
拦截器(目标项目相同):
public class CacheControlInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response.newBuilder()
.header("Cache-Control", "only-if-cached")
.build();
}
}
缓存和客户端声明:
long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MB
final Cache cache = new Cache(new File(getCacheDir(), "retrofit_cache"), SIZE_OF_CACHE);
OkHttpClient.Builder client = new OkHttpClient.Builder().cache(cache);
client.networkInterceptors().add(new CacheControlInterceptor());
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/users/")
.addConverterFactory(GsonConverterFactory.create())
.client(client.build())
.build();
调试CacheControlInterceptor的屏幕: screen
来自目标项目的代码(不工作):
缓存和客户端声明:
private OkHttpClient provideOkHttpClient() {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient.Builder();
okhttpClientBuilder.connectTimeout(30, TimeUnit.SECONDS);
okhttpClientBuilder.readTimeout(30, TimeUnit.SECONDS);
okhttpClientBuilder.writeTimeout(30, TimeUnit.SECONDS);
okhttpClientBuilder.addInterceptor(loggingInterceptor);
okhttpClientBuilder.addInterceptor(new JwtRenewInterceptor(getUserSession()));
okhttpClientBuilder.addInterceptor(new AutoLoginInterceptor(getUserSession()));
okhttpClientBuilder.addNetworkInterceptor(new CacheControlInterceptor());
long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MB
final Cache cache = new Cache(new File(getCacheDir(), "retrofit_cache"), SIZE_OF_CACHE);
okhttpClientBuilder.cache(cache);
return okhttpClientBuilder.build();
}
调试CacheControlInterceptor的屏幕:screen
答案 0 :(得分:1)
如果要对使用OkHttp缓存的所有请求应用一些标头,则应使用Application拦截器,而不是网络拦截器。否则,您不会给缓存机制提供返回缓存响应的机会。
它在OkHttp wiki上得到了很好的说明
所以很可能你的代码中发生的事情是你让Cache
存储响应,但是你从不使用它们,因为发送到Cache的请求缺少only-if-cached
标题。
尝试
okhttpClientBuilder.addInterceptor(new CacheControlInterceptor());
答案 1 :(得分:0)
实际上这个错误是由于我对http标头的不良推理造成的。我认为方法addHeader
或header
只会添加键Cache-Control
,然后添加值only-if-cached
。然而它只增加了价值!因为在我的目标项目的API中没有标题键Cache-Control
(与GitHub API不同),没有值存储的值only-if-cached
。