I am working on a android app which has requirement of offline mode , I am using retrofit 2 with cache control , but facing problem that cache files are not getting created and only file is created in that folder is named journal.I am posting my ApiClient.java file code here.
public class ApiClient {
public static final String BASE_URL = "http://www.something.com/";
private static Retrofit retrofit = null;
private static APIInterfaces apiInterface;
private static Context mcontext=getApplicationContext();
static Interceptor OFFLINE_INTERCEPTOR = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!isConnected()) {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
request = request.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
return chain.proceed(request);
}
};
static Interceptor ONLINE_INTERCEPTOR = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
okhttp3.Response response = chain.proceed(chain.request());
int maxAge = 60; // read from cache
return response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
}
};
protected static Retrofit getClient() {
if (retrofit == null) {
createFolder();
Gson gson = new GsonBuilder()
.setLenient()
.create();
OkHttpClient okHttpClient = new OkHttpClient
.Builder()
.cache(new Cache(new File(Environment.getExternalStorageDirectory() + File.separator + "something"), 10 * 1024 * 1024)) // 10 MB
.addInterceptor(OFFLINE_INTERCEPTOR)
.addNetworkInterceptor(ONLINE_INTERCEPTOR)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL).client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
public static APIInterfaces getApiInterface() {
if (apiInterface == null)
apiInterface = ApiClient.getClient().create(APIInterfaces.class);
return apiInterface;
}
private static boolean isConnected() {
try {
android.net.ConnectivityManager e = (android.net.ConnectivityManager) mcontext.getSystemService(
Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = e.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
} catch (Exception e) {
Log.w(TAG, e.toString());
}
return false;
}
public static boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (mcontext.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
return true;
} else {
ActivityCompat.requestPermissions((Activity) mcontext,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
return true;
}
}
private static void createFolder() {
if (isStoragePermissionGranted()) {
File folder = new File(Environment.getExternalStorageDirectory() + File.separator + "Something");
if (!folder.exists()) {
folder.mkdir();
}
}
}
}
Can anyone please explain what is problem with above code.
When you use interceptors to change headers it does not make any adjustments before CacheStrategy.isCacheable()
is called.
Try changing interceptors()
with networkInterceptors()
call.
Have a look here: https://github.com/square/okhttp/wiki/Interceptors
Also, you can't cache POST requests with OkHttp’s cache. You’ll need to store them using some other mechanism, see this
Other mechanisms:
There are several methods, one can be storing the online results to a local database and retrieve it from there if offline which most people do, the second option is to override OKHTTP
but that will be costly for a mobile device in terms of performance over benefit, the third one is obviously converting your POST API structure to GET
But, have a look here it contains a blog article too, which will help you.