【问题标题】:Retrofit2.1.0 and okhttp3 offline caching not workingRetrofit2.1.0 和 okhttp3 离线缓存不起作用
【发布时间】:2017-04-29 16:18:17
【问题描述】:

我正在尝试使用 Retrofit 和 OkHttp 来实现缓存。我在离线时收到“504 Unsatisfiable Request (only-if-cached)”作为错误。

OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
        builder.readTimeout(10, TimeUnit.SECONDS);
        builder.connectTimeout(5, TimeUnit.SECONDS);

        if (isDebug) {
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder.addInterceptor(logging);
        }

        builder.addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR)
                .addInterceptor(OFFLINE_INTERCEPTOR)
                .cache(provideCache());


        OkHttpClient client = builder.build();




        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(base_url)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

        reqinterface = retrofit.create(MyApiInterface.class);

  private static Cache provideCache(){
    Cache cache = null;
    try{

        cache = new Cache(new File(context.getCacheDir(),"baskin-cache"),
                10*1024*1024);
    }catch (Exception e){
        Log.i("zacharia","Could not create Cache");
    }
    return  cache;
}
  private static final Interceptor REWRITE_RESPONSE_INTERCEPTOR = new Interceptor() {
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        okhttp3.Response originalResponse = chain.proceed(chain.request());
        String cacheControl = originalResponse.header("Cache-Control");

        if (cacheControl == null || cacheControl.contains("no-store") || cacheControl.contains("no-cache") ||
                cacheControl.contains("must-revalidate") || cacheControl.contains("max-age=0")) {
            return originalResponse.newBuilder()
                    .header("Cache-Control", "public, max-age=" + 120)
                    .build();
        } else {
            return originalResponse;
        }
    }
};

private static final Interceptor OFFLINE_INTERCEPTOR = new Interceptor() {
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        if (!isOnline()) {
            Log.d("zacharia", "rewriting request");

            int maxStale = 60 * 60 * 24 * 7; // tolerate 4-weeks stale
            request = request.newBuilder()
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .build();
        }

        return chain.proceed(request);
    }
};

public static boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnectedOrConnecting();
}

在线时,我在日志中收到“D/OkHttp: Cache-Control: public, max-age=120”。离线时,'D/OkHttp:

【问题讨论】:

  • 问了之后找到解决办法了吗?

标签: android caching retrofit2 okhttp3


【解决方案1】:

您可以尝试调试方法 okhttp3.internal.cache.CacheInterceptor#intercept(Chain)okhttp3.Cache#get(Request) 看看为什么没有返回之前的响应。

【讨论】:

    猜你喜欢
    • 2018-08-06
    • 2012-07-07
    • 2019-03-25
    • 2015-06-01
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 2011-12-22
    • 2020-07-02
    相关资源
    最近更新 更多