android - OkHttp3 cache seems to be unchecked with Retrofit 2 -


i'm trying setup http cache using retrofit (2.1.0) , okhttp (3.3.1). have seen many posts related topic, none of them helped.

i wrote unit tests see how cache works. works fine, once integrated in app, magic ends. first show implementation , explain of investigation.

first, here retrofit instantiation :

    okhttpclient.builder httpbuilder = new okhttpclient.builder();     httplogginginterceptor logginginterceptor = new httplogginginterceptor();     interceptor.setlevel(httplogginginterceptor.level.headers);      okhttpclient client = httpbuilder             .addnetworkinterceptor(interceptor_response_set_cache)             .addnetworkinterceptor(interceptor_request_add_checksum)             .addinterceptor(logginginterceptor)             .cache(cachehttpclient).build();      retrofit retrofit = new retrofit.builder()             .addconverterfactory(gsonconverterfactory.create())             .client(client)             .baseurl(base_url)             .build(); 

here interceptor adding header set cache control:

    private final interceptor interceptor_response_set_cache = new interceptor() {          @override         public response intercept(chain chain) throws ioexception {             response response = chain.proceed(chain.request());             response = response.newbuilder()                     .header("cache-control", "max-age=600") //+ integer.tostring(3600 * 5)                     .build();             return response;         }     }; 

the last interceptor adds 2 url parameters:

 private static final interceptor interceptor_request_add_checksum = new interceptor() {         @override         public response intercept(interceptor.chain chain) throws ioexception {             httpurl url = chain.request().url();             url = url.newbuilder().addqueryparameter("rd", "random1").addqueryparameter("chk","check1").build();             request request = chain.request().newbuilder().url(url).build();             return chain.proceed(request);         }     }; 

finally, single method of service :

 @headers("cache-control: public, max-stale=500")  @get("/get_data")  call<dataresponse> getdata(@query("year") int year, @query("month") int month, @query("day") int day); 

about investigation, setup interceptor logger (app side, not network) see happening. can see lines such "cache-control: public, max-stale=500" in logs. means (at least me) header should give opportunity okhttp client check cache.

the cache seems correctly initialised. when create it, force initialisation , log urls present in cache. here how implemented:

file httpcachedirectory = new file(getcachedir(), "responses");         httpcachedirectory.getparentfile().mkdirs();         int cachesize = 10 * 1024 * 1024; // 10 mib         cache cache = new cache(httpcachedirectory, cachesize);         try {             cache.initialize();             iterator<string> iterator = cache.urls();             log.i(tag, "urls in cachehttpclient : ");             while (iterator.hasnext()) {                 log.i(tag, iterator.next());             }         } catch (ioexception e) {             e.printstacktrace();             log.i(tag, "cache not init");         } 

when launch app wifi available, expected responses. kill app, disable wifi , relaunch app. expect cache serve data @ moment. fails , can see okhttp printed lines in logs :

http failed: java.net.unknownhostexception: unable resolve host "my-domain.com": no address associated hostname

last thing, in rfc 2616, 1 can read :

max-stale : indicates client willing accept response has exceeded expiration time. if max-stale assigned value, client willing accept response has exceeded expiration time no more specified number of seconds. if no value assigned max-stale, client willing accept stale response of age.

when don't specify value, works (i response when wifi down). way found make "work". maybe misunderstand cache-control directive !?

at point i'm confused. able use okhttp cache system, somehow i'm missing something.

thank reading text !

use method create cached okkhttpclient

private okhttpclient createcachedclient(final context context) {         file httpcachedirectory = new file(context.getcachedir(), "cache_file");          cache cache = new cache(httpcachedirectory, 20 * 1024 * 1024);         okhttpclient okhttpclient = new okhttpclient();         okhttpclient.setcache(cache);         okhttpclient.interceptors().add(                 new interceptor() {                     @override                     public com.squareup.okhttp.response intercept(chain chain) throws ioexception {                         request originalrequest = chain.request();                         string cacheheadervalue = isonline(context)                                 ? "public, max-age=2419200"                                 : "public, only-if-cached, max-stale=2419200" ;                         request request = originalrequest.newbuilder().build();                         com.squareup.okhttp.response response = chain.proceed(request);                         return response.newbuilder()                                 .removeheader("pragma")                                 .removeheader("cache-control")                                 .header("cache-control", cacheheadervalue)                                 .build();                     }                 }         );         okhttpclient.networkinterceptors().add(                 new interceptor() {                     @override                     public com.squareup.okhttp.response intercept(chain chain) throws ioexception {                         request originalrequest = chain.request();                         string cacheheadervalue = isonline(context)                                 ? "public, max-age=2419200"                                 : "public, only-if-cached, max-stale=2419200" ;                         request request = originalrequest.newbuilder().build();                         com.squareup.okhttp.response response = chain.proceed(request);                         return response.newbuilder()                                 .removeheader("pragma")                                 .removeheader("cache-control")                                 .header("cache-control", cacheheadervalue)                                 .build();                     }                 }         );         return okhttpclient;     }      private boolean isonline(context context) {         connectivitymanager connectivity = (connectivitymanager) _context.getsystemservice(context.connectivity_service);         if (connectivity != null) {             networkinfo[] info = connectivity.getallnetworkinfo();             if (info != null)                 (int = 0; < info.length; i++)                     if (info[i].getstate() == networkinfo.state.connected) {                         return true;                     }         }         return false;           } 

call createcachedclient() method create okhttpclient add client retrofit

okhttpclient okhttpclient = createcachedclient(mainactivity.this); retrofit retrofit=new retrofit.builder()          .client(okhttpclient)          .baseurl(api)          .addconverterfactory(gsonconverterfactory          .create()).build(); 

add permission manifest

<uses-permission android:name="android.permission.access_network_state"/> 

if internet available first time call service , cache request,next time onwards upto 2419200 milliseconds use cache give response.it won't hit server upto 2419200 milliseconds if device if offline.


Comments

Popular posts from this blog

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -