okhttp3.4.1+retrofit2.1.0 implementation of offline caching in Android _android

Source: Internet
Author: User

About Retrofit+okhttp Strong here is not much to say, still do not know the classmate can go to Baidu. This article is mainly about how to use retrofit+okhttp to implement a simpler caching strategy:
When we request data in a network environment, if there is no cache or cache expiration, go to the server to fetch the data, and save the new cache, if there is a cache and does not expire, then use the cache directly. When we request data in a network-free environment, the cache is not expired, the cache is used directly, the cache expires, and the server data needs to be networked again.

Cache processing is also necessary to effectively reduce server load, reduce latency and improve user experience, and also make it easier for users to use apps even if they don't have a network.

There has been a doubt, since retrofit has been a package of okhttp, why has been said that retrofit+okhttp to use together, and then know that in fact, okhttp very important role is to some network request configuration, such as connection timeout, Read timeout, and some cache configurations, and so on.

One, add dependencies

Compile ' com.squareup.retrofit2:retrofit:2.1.0 '
Compile ' com.squareup.retrofit2:converter-gson:2.1.0 '
Compile ' com.squareup.okhttp3:okhttp:3.4.1 '
Compile ' com.squareup.okhttp3:logging-interceptor:3.4.1 '

Second, configure okhttpclient (set cache path and cache file size)

File Httpcachedirectory = new file (Environment.getexternalstoragedirectory (), "HttpCache"); Here in order to conveniently put the file in the SD card root directory HttpCache, generally placed in context.getcachedir ()
int cacheSize = 10 * 1024 * 1024;//Set cache file size is 10M
Cache cache = New cache (httpcachedirectory, cacheSize);
HttpClient = new Okhttpclient.builder ()
    . ConnectTimeout (timeunit.seconds)/Set the connection timeout
    . ReadTimeout (10, timeunit.seconds)/Read timeout
    . WriteTimeout (timeunit.seconds)/write timeout
    . Addnetworkinterceptor (rewrite_cache_ Control_interceptor)//Add a custom cache interceptor (explained later), note that you need to use. Addnetworkinterceptor cache
    /. Build
    ();

Third, the configuration retrofit

Retrofit = new Retrofit.builder ()
    . BaseURL (BaseURL)
    . Client (HttpClient)//Add Okhttpclient in
    . Addconverterfactory (Gsonconverterfactory.create ())
    . Build ();

Iv. Writing Interceptors

We know that the retrofit+okhttp cache is primarily implemented by interceptors, so the main effort is in the interceptor.

 Static Interceptor Rewrite_cache_control_interceptor = New Interceptor () {@Override public Response intercept (Chain
   Chain) throws IOException {Request request = Chain.request (); A lot of sample code on the web has no net judgment before request requests, in fact, no need to judge, no network automatically access cache//if (! Networkutil.getinstance (). IsConnected ()) {//request = Request.newbuilder ()//. CacheControl (Cachecontrol.force_ca
CHE)//only access cache//. build ();

   } Response Response = chain.proceed (request); if (Networkutil.getinstance (). IsConnected ()) {int maxage = 60;//cache expiration time in seconds return Response.newbuilder (). R
      Emoveheader ("Pragma")/clear header information, because if the server does not support, it will return some interference information, do not clear the following cannot be effective. Header ("Cache-control", "public, max-age=" + maxage)
   . build ();      else {//This code setting is invalid//int maxstale = 60 * 60 * 24 * 28;///No network, set timeout to 4 week/return Response.newbuilder ()// . Header ("Cache-control", "Public, only-if-cached, max-stale=" + maxstale)//. Removeheader ("Pragma")//. Build (
   );
  return response; }
 };

 

Here, in fact, we can achieve the beginning of the cache effect.

However, the above set of each interface cache time is the same, for example, I now want to make different interfaces of the cache data expiration time is not the same, and even some interfaces do not cache data, what should be done? It's simple, actually.

First we just need to add the @headers parameter in front of the interface (Max-age represents the cache time, in seconds, in the example, the cache expiration time is 60s, how much time you want to set itself), and do not set the @headers parameter without caching .

 @Headers ("Cache-control:public, max-age=60")
 @GET ("getbusiness.action")//store information
 call< Restaurantinfomodel> Getrestaurantinfo (@Query ("UserId") string userId, @Query ("Businessid") string businessid);

At the same time, our cache interceptor has to do a simple modification (remove the previous annotation code)

 Static Interceptor Rewrite_cache_control_interceptor = New Interceptor () {
  @Override public
  Response Intercept (Chain Chain) throws IOException {

   Request request = Chain.request ();
   Response Response = chain.proceed (request);

   if (Networkutil.getinstance (). IsConnected ()) {
    //Get header information
    String CacheControl =request.cachecontrol (). ToString ();
    Return Response.newbuilder ()
      . Removeheader ("Pragma")/clear header information, because if the server does not support, it returns some interference information, do not clear the following cannot take effect
      . Header (" Cache-control ", CacheControl)
      . Build ();
   return response;
  }
 ;

Attention

1. Interface that can only cache get requests, cannot cache the interface of Post requests

2.OkHttpClient need to use. Addnetworkinterceptor to add a cache interceptor, you cannot use. Addinterceptor, and you don't need both.

3. This method does not require any server-side operations, applicable to the server side there is no other caching policy, if the server side has its own cache policy code should be modified to adapt to the server side.

Attach All code:

/** * Simple Package Retroit initialization class/public class Initretrofit {private static String BaseURL = "http://202.171.212.154:8080/hh/
 ";
 private static okhttpclient httpclient;

 private static retrofit retrofit; public static Retrofit Initretrofit () {//cache path and size File httpcachedirectory = new File (environment.getexternalstoragedir
  Ectory (), "HttpCache");
  int cacheSize = 10 * 1024 * 1024;

  Cache cache = New cache (httpcachedirectory, cacheSize);
  Log Interceptor Httplogginginterceptor Interceptor = new Httplogginginterceptor ();

  Interceptor.setlevel (HttpLoggingInterceptor.Level.BODY); HttpClient = new Okhttpclient.builder (). ConnectTimeout (timeunit.seconds)/Set the connection timeout. ReadTimeout (timeunit.se conds)/Read timeout. WriteTimeout (timeunit.seconds)/write timeout. Addinterceptor (Interceptor)//Add log Interceptor. Addnetworkinterc

  Eptor (Rewrite_cache_control_interceptor)//Add Cache Interceptor. Cache (cached)//Add Caching in. build (); Retrofit = new Retrofit.builder (). BaseURL (BaseURL). Client (HttpclienT). Addconverterfactory (Gsonconverterfactory.create ()). build ();
 return retrofit;
 public static Retrofitapi GetService () {return Initretrofit (). Create (Retrofitapi.class); /////cache interceptor, different interface different cache//static Interceptor Rewrite_cache_control_interceptor = New Interceptor () {//@Override//Pub  Lic Response Intercept (Chain Chain) throws IOException {///Request request = Chain.request ();//Response Response
= Chain.proceed (request);    if (Networkutil.getinstance (). IsConnected ()) {//String CacheControl =request.cachecontrol (). toString ();// return Response.newbuilder ()//. Removeheader ("Pragma")//Clear header information, because if the server does not support, it returns some interference information, does not clear the following cannot take effect//. Header ("Cache
-control ", CacheControl)//. Build ();
}//return response;

 //  }
// }; Cache Interceptor, unified cache 60s static Interceptor Rewrite_cache_control_interceptor = New Interceptor () {@Override public Response
   Intercept (Chain Chain) throws IOException {Request request = Chain.request (); REsponse response = chain.proceed (request);
      if (Networkutil.getinstance (). IsConnected ()) {int maxage = 60*60*24*2;//cache expiration time, in seconds return Response.newbuilder () . Removeheader ("Pragma")/clear header information, because if the server does not support, will return some interference information, do not clear the following cannot take effect. Header ("Cache-control", "public, max-age=" + ma
   xage). build ();
  return response;
}
 };

 }

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.