1

私は、Android のキャッシングと Retrofit/OKHttp3 から始めています。アプリのオフライン モード/サーバー ダウンをサポートする必要があり、それをサポートするためにキャッシュを正しく構成する方法を見つけようとしています。アイデアは、サーバーが利用可能になったときにサーバーから新しいコピーを取得することです (または、何も変更されていない場合は 304)。サーバーがダウンしている場合、またはアプリがオフラインの場合は、キャッシュされた応答をフェッチする必要があります。

私はこのようにキャッシュコントロールを設定しました:

Cache-Control: no-transform, max-age=0, max-stale=50, private

これはかなりうまく機能しますが、「max-stale」が経過した場合でも OKHttp がキャッシュされた応答を提供する理由がわかりません。max-stale 期間が経過したため、50 秒後に 504 - Unsatisfiable リクエストが返されると思いましたか?

これは、OKHttp に使用するインターセプターです。

.addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        try {
                            if (!NetworkUtil.isNetworkAvailable(model.getApplicationContext())) {
                                return getCachedResponse(chain);
                            }
                            Request request = chain.request();
                            return chain.proceed(request);
                        } catch (Exception exception) {
                            return getCachedResponse(chain);
                        }
                    }
                })

    private static Response getCachedResponse(Interceptor.Chain chain) throws IOException {
    Request request = chain.request().newBuilder()
            .cacheControl(CacheControl.FORCE_CACHE)
            .removeHeader("Pragma")
            .build();

    Response forceCacheResponse = chain.proceed(request);
    return forceCacheResponse.newBuilder()
            .build();
}

max-stale 期間が経過した後にキャッシュされた応答を提供しないようにキャッシュを構成する方法はありますか?

4

1 に答える 1

3

いつものように、質問をすると答えが見つかります。CacheControl.FORCE_CACHE を使用したため、max-stale 期間が経過した後もキャッシュがコンテンツを提供し続けることを理解しています。これにより、「only-if-cache」フラグが追加され、さらに max-stale が非常に高い値に設定され、サーバーが最初に渡した max-stale 値が上書きされます。私が定義した max-stale 値を持つ別の cachecontrol を作成することで解決しました:

    private static Response getCachedResponse(Interceptor.Chain chain) throws IOException {

    CacheControl cacheControl = new CacheControl
            .Builder()
            .onlyIfCached()
            .maxStale(5, TimeUnit.MINUTES).build();

    Request request = chain.request().newBuilder()
            .cacheControl(cacheControl)
            .removeHeader("Pragma")
            .build();

    Response forceCacheResponse = chain.proceed(request);
    return forceCacheResponse.newBuilder()
            .build();
}
于 2016-02-10T12:20:01.760 に答える