1

I am using okhttp3 to make requests to the server, not using retrofit. My idea is to make a call and save the response in cache for 15 minutes. if during those 15 minutes, the request is made again, recover the cache response, after 15 minutes, request it again from the server.

This is my code:

public class Handler_JSON_get {

    public Handler_JSON_get() {

    }

    public String makeServiceCall(String url, JSONObject data) {
        final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

        Cache cache = new Cache(new File(Environment.getExternalStorageDirectory().getPath() + "/Android/data/MY_PACKAGE/", "cache"), 10 * 1024 * 1024);

        OkHttpClient okHttpClient;

            Log.i("2134","Usando caché");
             okHttpClient = new OkHttpClient.Builder()
                    .addNetworkInterceptor(provideCacheInterceptor())
                    .readTimeout(45, TimeUnit.SECONDS)
                    .protocols(Arrays.asList(Protocol.HTTP_1_1))
                    .addInterceptor(provideCacheInterceptor())
                    .cache(cache)
                    .build();

        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        try {
            Response response = okHttpClient.newCall(request).execute();

            Log.i(TAG,"Response:"+response.code());

            return response.body().string();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    Interceptor provideCacheInterceptor() {
        return new Interceptor() {
            @Override
            public Response intercept(Interceptor.Chain chain) throws IOException {
                Response response = chain.proceed(chain.request());
                CacheControl cacheControl = new CacheControl.Builder()
                        .maxAge(15, TimeUnit.MINUTES)
                        .build();

                return response.newBuilder()
                        .header("cache", cacheControl.toString())
                        .build();
            }
        };
    }
}

The problem is that he always makes the call to the server and I have many doubts.

okhttp3 is responsible for seeing if there is a cached response in the storage?

The call saves a journal file, is this the correct file?

What am I missing or what am I doing wrong?

I have seen that there are quite a few questions about it, but I can not make those answers compatible with my code.

I would sincerely appreciate the parts that are necessary in my code to function properly, I start to go crazy.

Thanks in advance.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Sergio76
  • 3,835
  • 16
  • 61
  • 88
  • I think you're close, check out this https://stackoverflow.com/questions/29119253/retrofit-okhttp-client-how-to-cache-the-response – goudarziha Jun 28 '19 at 15:05

1 Answers1

1

It took me some time to spot it : The correct header name is Cache-Control, not cache :

return response.newBuilder()
                    .header("Cache-Control", cacheControl.toString())
                    .build();

Also it seems that adding the interceptor with addNetworkInterceptor is sufficient, it is not necessary to also add it with addInterceptor

bwt
  • 17,292
  • 1
  • 42
  • 60
  • That's strange, I used your code, the cache was not used at first, but after I changed the header name, it worked. – bwt Jul 02 '19 at 08:47
  • Maybe there is another header that prevent okhttp to put the response in the cache – bwt Jul 02 '19 at 08:49
  • You can log them with something like `Log.i(TAG, response.headers().toString());` in the interceptor – bwt Jul 02 '19 at 08:51
  • Maybe I'm not understanding, sorry. I always get a 200 response from the server. How do you know you are showing a cached response? – Sergio76 Jul 02 '19 at 14:38
  • I used a test page wich contains the time – bwt Jul 02 '19 at 14:52
  • application interceptor are always called, network interceptor are called only if the response is not cached. Your interceptor is registered as both : if you add a log in `intercept`, you will see it 2 times if not cached, 1 time if cached – bwt Jul 02 '19 at 14:54
  • The error was mine, because of something related to storage. Your solution is perfect. I'm happy to give you 100 points. Thank you for all of your help :)) – Sergio76 Jul 02 '19 at 20:40