Search code examples
androidcachingcache-controlokhttp

Okhttp cache file not created(Not working okhttp caching)


i want to say that i use the okhttp caching with Retrofit but cache file not created while i write the right code because i create a sample app where is working done but when i use same code in my project i am not understood why not create cache file.

Here is my code :

private Context context;
private PrefManager prefManager;

private String BEARER = "Bearer ";
private String APP_JSON = "application/json";
private String OUTPUT_ACCEPT = "Accept";
private String AUTHERIZATION = "Authorization";
private int CACHE_SIZE_BYTES = 10 * 1024 * 1024;
private String TAG = OkHttpClientModule.class.getSimpleName();


@Provides
public OkHttpClient okHttpClient(Cache cache, Interceptor interceptor, StethoInterceptor stethoInterceptor, HttpLoggingInterceptor httpLoggingInterceptor) {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.addInterceptor(interceptor);
    builder.cache(cache);

     builder.connectTimeout(10, TimeUnit.SECONDS);
     builder.writeTimeout(10, TimeUnit.SECONDS);
     builder.readTimeout(30, TimeUnit.SECONDS);
    if (BuildConfig.DEBUG) {
        builder.addNetworkInterceptor(stethoInterceptor);
        builder.interceptors().add(httpLoggingInterceptor);
    }

    OkHttpClient client = builder.build();
    return client;
}

@Provides
public PrefManager getManager(Context context) {
    return new PrefManager(context);
}

@Provides
public StethoInterceptor getSteltho() {
    return new StethoInterceptor();
}


@Provides
public Cache cache(File cacheFile) {
    Cache cache = null;
    try {
        cache = new Cache(cacheFile, CACHE_SIZE_BYTES);
        Log.e("TAG", " cache created " + cache.directory().getPath());
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("TAG", " cache exception " + e.getLocalizedMessage());
    }
    return cache;
}

@Provides
@RandomUserApplicationScope
public File file(@ApplicationContext Context ctx) {
    this.context = ctx;
    File file = new File(ctx.getCacheDir(), "httpcache");
    return file;
}


@Provides
public Interceptor getIntercepter() {
    final String mAuth = "";//Credentials.basic(BaseRequest.AUTH_USERNAME, BaseRequest.AUTH_PASSWORD);
    Interceptor headerAuthorizationInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            if (!NetworkUtils.isConnected(context)) {
                Log.e(TAG, "response from cache ");
                Request request = chain.request();
                CacheControl cacheControl = new 
                   CacheControl.Builder().maxStale(1, 
                   TimeUnit.DAYS).build();

                request = request.newBuilder().cacheControl(cacheControl).build();
                String rawJson = chain.proceed(request).body().string();

                Log.e(BuildConfig.APPLICATION_ID, String.format("req response cache raw JSON response is: %s", rawJson));
                return chain.proceed(request);
            } else {

                Log.e(TAG, "response from network");
                CacheControl cacheControl = new CacheControl.Builder().maxAge(1, TimeUnit.HOURS).build();
                prefManager = new PrefManager(context);
                String token = prefManager.getPreference(AppConstant.HEADER_TOKEN);
                Request.Builder request = chain.request().newBuilder();
                request.addHeader(OUTPUT_ACCEPT, APP_JSON);
                request.addHeader(AUTHERIZATION, BEARER + token);
                request.header(CACHE_CONTROL, cacheControl.toString());
                //request.cacheControl(CacheControl.FORCE_CACHE);

                Response response = chain.proceed(request.build());


                return response;
            }
        }
    };
    return headerAuthorizationInterceptor;
}


@Provides
public HttpLoggingInterceptor httpLoggingInterceptor() {
    HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
    httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    return httpLoggingInterceptor;
}

And i am check cache file in File explorer but showing here


Solution

  • You can create a Context in your MainActivity, like below:

    public static Context mContext;
    

    In your onCreate(), you can add:

    mContext = getApplicationContext();
    

    Then, in a separate file, example RetrofitCachingInstance:

    public class RetrofitCachingInstance {
    
    private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = chain -> {
    
        Response originalResponse = chain.proceed(chain.request());
        return originalResponse.newBuilder()
                .removeHeader("Pragma")
                .header("Cache-Control",
                        String.format(Locale.ENGLISH, "max-age=%d", 60))
                .build();
    };
    
    private static Retrofit retrofit;
    private static final String BASE_URL = "YOUR_JSON_URL";
    
    public static Retrofit getRetrofitInstance() {
    
        if (retrofit == null) {
            OkHttpClient.Builder client = new OkHttpClient.Builder();
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            client.addInterceptor(loggingInterceptor);
            client.addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR);
            client.addInterceptor(provideOfflineCacheInterceptor());
            client.cache(getCache(MainActivity.mContext));
    
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(client.build())
                    .addConverterFactory(GsonConverterFactory.create()) 
                    // using Gson for deserialization in this case
                    .build();
        }
        return retrofit;
    }
    
    private static Interceptor provideOfflineCacheInterceptor() {
    
        return chain -> {
    
            try {
                return chain.proceed(chain.request());
    
            } catch (Exception e) {
    
                CacheControl cacheControl = new CacheControl.Builder()
                        .onlyIfCached()
                        .maxStale(2, TimeUnit.DAYS) 
                // accept cached responses up to 2 days old, else hit network request again
                        .build();
    
                Request offlineCachingRequest = chain.request().newBuilder()
                        .removeHeader("Pragma")
                        .cacheControl(cacheControl)
                        .build();
    
                return chain.proceed(offlineCachingRequest);
            }
        };
    }
    
    private static Cache getCache(Context context) {
    
        int cacheSize = 10 * 1024 * 1024; // Cache size is only 10 MB maximum
    
        return new Cache(MainActivity.mContext.getCacheDir(), cacheSize);
    
       }
    }
    

    This should work. Hope this is helpful.