Search code examples
androidretrofit2okhttp

Detect if OkHttp response comes from cache (with Retrofit)


Is there a way to detect if a Retrofit response comes from the configured OkHttp cache or is a live response?

Client definition:

Cache cache = new Cache(getCacheDirectory(context), 1024 * 1024 * 10);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .cache(cache)
            .build();

Api definition:

@GET("/object")
Observable<Result<SomeObject>> getSomeObject();

Example call:

RetroApi retroApi = new Retrofit.Builder()
            .client(okHttpClient)
            .baseUrl(baseUrl)
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(RetroApi.class);

result = retroApi.getSomeObject().subscribe((Result<SomeObject> someObjectResult) -> {
     isFromCache(someObjectResult); // ???
});

Solution

  • Any time you have an okhttp3.Response (retrofit2.Response.raw()), you can check if the response is from the cache.

    To quote Jesse Wilson:

    There are a few combos.

    .networkResponse() only – your request was served from network exclusively.

    .cacheResponse() only – your request was served from cache exclusively.

    .networkResponse() and .cacheResponse() – your request was a conditional GET, so headers are from the network and body is from the cache.

    So for your example, the isFromCache method would look like:

    boolean isFromCache(Result<?> result) {
      return result.response().raw().networkResponse() == null;
    }