Search code examples
androidcachingretrofitokhttp

OKHTTP - After setting cache how to cache certain retrofit http responses


To cache in android okhttp i have the following code set up:

final @Nullable File baseDir = context.getCacheDir();
if (baseDir != null) {
    final File cacheDir = new File(baseDir, "HttpResponseCache");
okHttpClient.setCache(new Cache(cacheDir, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE));
}

This sets my cache to a directory I call HttpResponseCache. How do I cache a certain response now? I dont want to cache all retrofit responses only selected ones?


Solution

  • Just to let you know that this answer is using Retrofit 2 beta. For the purpose of this answer there is not much difference.

    I am assuming that you have something like this to get a retrofit client.

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(new ErrorHandlingCallbackAdapter.ErrorHandlingCallAdapterFactory());
    

    I hope you also have a method like this:

    public static <S> S createCachedService(Context context, Class<S> serviceClass) {
    
        Retrofit retrofit = builder.client(sOkHttpClient).build();
        return retrofit.create(serviceClass);
    }
    

    But you should have 2 of these methods. One that adds the okhttp client and one that does not.

    public static <S> S createService(Context context, Class<S> serviceClass) {
    
        Retrofit retrofit = builder.build();
        return retrofit.create(serviceClass);
    }
    

    Whenever you need to make a call that is cached just use the cached service creator.

    It is my understanding that you can also add a @Header annotation to an endpoint if you want all requests to that endpoint to skip the cache. okhttp should respect you Cache-Control headers. something like

    public interface GitHubService {
    
        @Headers("Cache-Control: no-cache")
        @GET("/users/{user}/repos")
        Call<List<Repo>> listRepos(@Path("user") String user);
    
    }