Actualización de solicitud y respuesta fuera de línea

Ya he leído muchas preguntas y respuestas sobre mi problema, pero sigo sin entender cómo resolverlo.

Necesito obtener la respuesta del servidor y almacenarla en caché. Después de eso, cuando el dispositivo está fuera de línea, quiero usar la respuesta en caché. Cuando el dispositivo está en línea, quiero obtener la respuesta exactamente del servidor.

No parece tan complicado.

Aquí está la forma (muestras de código) que trato de hacer esto:

1) Método para crear una caché

Cache provideOkHttpCache() {
        int cacheSize = 10 * 1024 * 1024; // 10 MiB
        Cache cache = new Cache(this.getCacheDir(), cacheSize);
        return cache;
    }

2) Crear un interceptor para modificar los encabezados de control de caché

 Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {

            CacheControl.Builder cacheBuilder = new CacheControl.Builder();
            cacheBuilder.maxAge(0, TimeUnit.SECONDS);
            cacheBuilder.maxStale(365, TimeUnit.DAYS);
            CacheControl cacheControl = cacheBuilder.build();

            Request request = chain.request();

            if (isOnline()) {
                request = request.newBuilder()
                        .cacheControl(cacheControl)
                        .build();
            }
            okhttp3.Response originalResponse = chain.proceed(request);
            if (isOnline()) {
                int maxAge = 20; // read from cache
                okhttp3.Response response = originalResponse.newBuilder()
                        .header("cache-control", "public, max-age=" + maxAge)
                        .build();
                return response;
            } else {
                int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
                okhttp3.Response response = originalResponse.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .build();
                return response;
            }
        }
    };

3) Crear OkHttpClient y Retrofit

OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(httpLoggingInterceptor)
            .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
            .cache(provideOkHttpCache())
            .build();

    retrofit = new Retrofit.Builder()
            .client(okHttpClient)
            .baseUrl("https://randomuser.me/")
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();

4) Método para hacer una llamada de red

private void networkCall() {
    Log.v(TAG, "networkCall() is called");
    Call<RandomUsers> randomUsersCall = getRandomUserService().getRandomUsers(10);
    randomUsersCall.enqueue(new Callback<RandomUsers>() {
        @Override
        public void onResponse(Call<RandomUsers> call, @NonNull Response<RandomUsers> response) {
            if (response.isSuccessful()) {
                try {
                    Log.v(TAG, "headers = " + response.headers());

                } catch (Exception e) {
                    e.printStackTrace();
                }

                mAdapter = new RandomUserAdapter();
                mAdapter.setItems(response.body().getResults());
                recyclerView.setAdapter(mAdapter);
            } else if (response.code() == 504) {
                Log.v(TAG, "response body = " + response.raw().cacheResponse());
            }
        }

        @Override
        public void onFailure(Call<RandomUsers> call, Throwable t) {
            Log.v("cache-control", "response failure");
        }
    });
}

Entonces, aquí está el problema: la aplicación nunca pasa al bloque de código fuera de línea en la p.2. Si la edad máxima sigue siendo legal, Retrofit usa la respuesta en caché. Si la respuesta se almacenó en caché hace algún tiempo y la edad máxima no es legal, hay dos casos:

1) El dispositivo está en línea:Retrofit hacer una nueva solicitud al servidor (todo está bien)

2) El dispositivo está fuera de línea: método de devolución de llamadaonFailure dentronetworkCall() se llama (p.4 de ejemplos de código)

¿Qué hay de malo en mi código? Realmente no entiendo por qué la aplicación no puede usar el caso fuera de línea de control de caché.

Perdón por demasiado texto. ¡Gracias!

Respuestas a la pregunta(1)

Su respuesta a la pregunta