改造2缓存 - 拦截器链

时间:2016-09-12 13:02:54

标签: android caching retrofit2

我需要实现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

2 个答案:

答案 0 :(得分:1)

如果要对使用OkHttp缓存的所有请求应用一些标头,则应使用Application拦截器,而不是网络拦截器。否则,您不会给缓存机制提供返回缓存响应的机会。 它在OkHttp wiki上得到了很好的说明 enter image description here

所以很可能你的代码中发生的事情是你让Cache存储响应,但是你从不使用它们,因为发送到Cache的请求缺少only-if-cached标题。

尝试 okhttpClientBuilder.addInterceptor(new CacheControlInterceptor());

答案 1 :(得分:0)

实际上这个错误是由于我对http标头的不良推理造成的。我认为方法addHeaderheader只会添加键Cache-Control,然后添加值only-if-cached。然而它只增加了价值!因为在我的目标项目的API中没有标题键Cache-Control(与GitHub API不同),没有值存储的值only-if-cached