I've written the following code to fetch & cache MarvelAPI data on to my device. The cache folder contains cache data but Retrofit NEVER reads the cache when offline, instead it gives 504 Unsatisfiable request error.
I'm not really sure what am I doing wrong.
private static final String HTTP_CACHE_PATH = "http-cache";
private static final String CACHE_CONTROL = "Cache-Control";
private static final String PRAGMA = "Pragma";
@Provides
@NetworkComponentScope
public Retrofit providesRetrofit(OkHttpClient okHttpClient, GsonConverterFactory gsonConverterFactory, String baseUrl) {
return new Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(gsonConverterFactory)
.baseUrl(baseUrl)
.build();
}
@Provides
@NetworkComponentScope
public OkHttpClient providesOkHttpClient(Context context, OkHttpClient.Builder builder, HttpLoggingInterceptor okhttpLoggingInterceptor, Cache cache) {
builder.cache(cache);
builder.addNetworkInterceptor(provideCacheInterceptor(5000));
builder.addInterceptor(provideOfflineCacheInterceptor(context, 5000));
if(BuildConfig.DEBUG) {
builder.addInterceptor(okhttpLoggingInterceptor);
}
return builder.build();
}
@Provides
@NetworkComponentScope
@PicassoLoggingInterceptor
public OkHttpClient providesOkHttpClientForPicasso(OkHttpClient.Builder builder, HttpLoggingInterceptor okhttpLoggingInterceptor) {
if(BuildConfig.DEBUG) {
builder.addInterceptor(okhttpLoggingInterceptor);
}
return builder.build();
}
@Provides
public OkHttpClient.Builder provideOkHttpClientBuilder() {
OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient().newBuilder();
okhttpClientBuilder.connectTimeout(25, TimeUnit.SECONDS);
okhttpClientBuilder.readTimeout(25, TimeUnit.SECONDS);
return okhttpClientBuilder;
}
@Provides
@NetworkComponentScope
public Cache providesCache(Context context) {
File httpCacheDirectory = new File(context.getCacheDir(), "marvel_responses");
int cacheSize = 10 * 1024 * 1024; // 10 MB
return new Cache(httpCacheDirectory, cacheSize);
}
@Provides
public HttpLoggingInterceptor providesOkhttpLoggingInterceptor() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
return interceptor;
}
private Interceptor provideCacheInterceptor(final int maxAgeMin) {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(maxAgeMin, TimeUnit.MINUTES)
.build();
return response.newBuilder()
.removeHeader(PRAGMA)
.removeHeader(CACHE_CONTROL)
.header(CACHE_CONTROL, cacheControl.toString())
.build(); }
};
}
public Interceptor provideOfflineCacheInterceptor(final Context context, final int maxStaleDay) {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!Utils.isNetworkAvailable(context)) {
CacheControl cacheControl = new CacheControl.Builder()
.maxStale(maxStaleDay, TimeUnit.DAYS)
.build();
request = request.newBuilder()
.cacheControl(cacheControl)
.build();
}
return chain.proceed(request);
}
};
}
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
compile "com.squareup.retrofit2:adapter-rxjava:2.2.0"
compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
When you use cache-control headers to forbid the network, and the cache isn鈥檛 fresh enough to be returned, this is what happens.
Note that presence on the filesystem doesn't mean the response is fresh; it merely means it is eligible for consideration.
@swankjesse Theoretically cache is fresh since the time limits that are set in the code are all very long. Besides I load data from the network then turn off the wifi and reopen the app and get this response. I'm not sure where in the code I'm making the mistake
SOmetimes I get the following error too:
HTTP FAILED: java.net.UnknownHostException: Unable to resolve host "gateway.marvel.com": No address associated with hostname
This is a better question for Stack Overflow. There鈥檚 a few nice explanations of cache behavior there, and if your case isn鈥檛 covered it鈥檚 a useful resource for other people running into the same problem.
I have posted the question on Stackoverflow but probably no one knows the answer to this problem. That's why I have come here to seek assistance.
Most helpful comment
I have posted the question on Stackoverflow but probably no one knows the answer to this problem. That's why I have come here to seek assistance.