国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

okhttp3.4.1+retrofit2.1.0實(shí)現(xiàn)離線緩存的示例

2019-12-12 01:29:14
字體:
供稿:網(wǎng)友

關(guān)于Retrofit+OkHttp的強(qiáng)大這里就不多說了,還沒了解的同學(xué)可以自行去百度。這篇文章主要講如何利用Retrofit+OkHttp來實(shí)現(xiàn)一個(gè)較為簡單的緩存策略:

即有網(wǎng)環(huán)境下我們請求數(shù)據(jù)時(shí),如果沒有緩存或者緩存過期了,就去服務(wù)器拿數(shù)據(jù),并且將新緩存保存下來,如果有緩存而且沒有過期,則直接使用緩存。無網(wǎng)環(huán)境下我們請求數(shù)據(jù)時(shí),緩存沒過期則直接使用緩存,緩存過期了則無法使用,需要重新聯(lián)網(wǎng)獲取服務(wù)器數(shù)據(jù)。

緩存處理還是很有必要的,它有效的減少服務(wù)器負(fù)荷,降低延遲提升用戶體驗(yàn),同時(shí)也方便用戶即使在沒網(wǎng)絡(luò)的情況下也能使用APP。

之前一直有一個(gè)疑惑,既然Retrofit已經(jīng)是對OkHttp的一個(gè)封裝了,為什么還一直說Retrofit+OkHttp要一起搭配使用,后來才知道其實(shí)OKHttp很重要的一個(gè)作用,就是對一些網(wǎng)絡(luò)請求的配置,例如連接超時(shí),讀取超時(shí),以及一些緩存配置等。

一、添加依賴

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'

二、配置OkHttpClient(設(shè)置緩存路徑和緩存文件大小)

File httpCacheDirectory = new File(Environment.getExternalStorageDirectory(), "HttpCache");//這里為了方便直接把文件放在了SD卡根目錄的HttpCache中,一般放在context.getCacheDir()中int cacheSize = 10 * 1024 * 1024;//設(shè)置緩存文件大小為10MCache cache = new Cache(httpCacheDirectory, cacheSize);httpClient = new OkHttpClient.Builder()    .connectTimeout(10, TimeUnit.SECONDS)//設(shè)置連接超時(shí)    .readTimeout(10, TimeUnit.SECONDS)//讀取超時(shí)    .writeTimeout(10, TimeUnit.SECONDS)//寫入超時(shí)    .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)//添加自定義緩存攔截器(后面講解),注意這里需要使用.addNetworkInterceptor    .cache(cache)//把緩存添加進(jìn)來    .build();

三、配置Retrofit

retrofit = new Retrofit.Builder()    .baseUrl(baseUrl)    .client(httpClient)//把OkHttpClient添加進(jìn)來    .addConverterFactory(GsonConverterFactory.create())    .build();

四、編寫攔截器

我們知道其實(shí)Retrofit+OkHttp的緩存主要通過攔截器實(shí)現(xiàn),所以主要做的功夫也在攔截器里面。

 static Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {  @Override  public Response intercept(Chain chain) throws IOException {   Request request = chain.request();   //網(wǎng)上很多示例代碼都對在request請求前對其進(jìn)行無網(wǎng)的判斷,其實(shí)無需判斷,無網(wǎng)自動(dòng)訪問緩存//   if(!NetworkUtil.getInstance().isConnected()){//    request = request.newBuilder()//      .cacheControl(CacheControl.FORCE_CACHE)//只訪問緩存//      .build();//   }   Response response = chain.proceed(request);   if (NetworkUtil.getInstance().isConnected()) {    int maxAge = 60;//緩存失效時(shí)間,單位為秒    return response.newBuilder()      .removeHeader("Pragma")//清除頭信息,因?yàn)榉?wù)器如果不支持,會(huì)返回一些干擾信息,不清除下面無法生效      .header("Cache-Control", "public ,max-age=" + maxAge)      .build();   } else {    //這段代碼設(shè)置無效//    int maxStale = 60 * 60 * 24 * 28; // 無網(wǎng)絡(luò)時(shí),設(shè)置超時(shí)為4周//    return response.newBuilder()//      .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)//      .removeHeader("Pragma")//      .build();   }   return response;  } };

到這里,其實(shí)已經(jīng)可以實(shí)現(xiàn)了我們開頭所說的緩存效果了。

但是,上面設(shè)置的每個(gè)接口緩存時(shí)間都一樣,例如我現(xiàn)在想讓不同接口的緩存數(shù)據(jù)失效時(shí)間都不一樣,甚至有些接口不緩存數(shù)據(jù),應(yīng)該怎么做呢?其實(shí)也很簡單

首先我們只需要在接口前面添加@Headers參數(shù)(max-age代表緩存時(shí)間,單位為秒,示例中表示緩存失效時(shí)間為60s,想要多少時(shí)間可以自行設(shè)置),不設(shè)置@Headers參數(shù)則不進(jìn)行緩存。

@Headers("Cache-Control:public ,max-age=60")@GET("getBusiness.action")//商店信息Call<RestaurantInfoModel> getRestaurantInfo(@Query("userId") String userId,@Query("businessId") String businessId);

同時(shí),我們的緩存攔截器也要做下簡單的修改(去掉了之前的注釋代碼)

 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()) {    //獲取頭部信息    String cacheControl =request.cacheControl().toString();    return response.newBuilder()      .removeHeader("Pragma")//清除頭信息,因?yàn)榉?wù)器如果不支持,會(huì)返回一些干擾信息,不清除下面無法生效      .header("Cache-Control", cacheControl)      .build();   }   return response;  } };

*注意:

1.只能緩存Get請求的接口,不能緩存Post請求的接口

2.OkHttpClient需要用.addNetworkInterceptor添加緩存攔截器,不能使用.addInterceptor,也無需兩者同時(shí)使用。

3.此方法無需服務(wù)器端任何操作,適用于服務(wù)器端沒有其他緩存策略,如果服務(wù)器端有自己的緩存策略代碼應(yīng)該做相應(yīng)的修改,以適應(yīng)服務(wù)器端。

附上所有代碼:

/** * 簡單封裝的Retroit初始化類 */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() {  //緩存路徑和大小  File httpCacheDirectory = new File(Environment.getExternalStorageDirectory(), "HttpCache");  int cacheSize = 10 * 1024 * 1024;  Cache cache = new Cache(httpCacheDirectory, cacheSize);  //日志攔截器  HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();  interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);  httpClient = new OkHttpClient.Builder()    .connectTimeout(10, TimeUnit.SECONDS)//設(shè)置連接超時(shí)    .readTimeout(10, TimeUnit.SECONDS)//讀取超時(shí)    .writeTimeout(10, TimeUnit.SECONDS)//寫入超時(shí)    .addInterceptor(interceptor)//添加日志攔截器    .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)//添加緩存攔截器    .cache(cache)//把緩存添加進(jìn)來    .build();  retrofit = new Retrofit.Builder()    .baseUrl(baseUrl)    .client(httpClient)    .addConverterFactory(GsonConverterFactory.create())    .build();  return retrofit; } public static RetrofitAPI getService() {  return initRetrofit().create(RetrofitAPI.class); }// //緩存攔截器,不同接口不同緩存// 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()) {//    String cacheControl =request.cacheControl().toString();//    return response.newBuilder()//      .removeHeader("Pragma")//清除頭信息,因?yàn)榉?wù)器如果不支持,會(huì)返回一些干擾信息,不清除下面無法生效//      .header("Cache-Control", cacheControl)//      .build();//   }//   return response;//  }// }; //緩存攔截器,統(tǒng)一緩存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;//緩存失效時(shí)間,單位為秒    return response.newBuilder()      .removeHeader("Pragma")//清除頭信息,因?yàn)榉?wù)器如果不支持,會(huì)返回一些干擾信息,不清除下面無法生效      .header("Cache-Control", "public ,max-age=" + maxAge)      .build();   }   return response;  } };}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 公安县| 阿拉善盟| 秦安县| 婺源县| 宝丰县| 吴江市| 博客| 雅江县| 顺昌县| 肇庆市| 如东县| 岳普湖县| 古丈县| 太和县| 康保县| 双牌县| 宁陕县| 桐梓县| 大英县| 赣榆县| 城口县| 贵州省| 千阳县| 涿鹿县| 柳河县| 华容县| 阿尔山市| 祁门县| 翁牛特旗| 白朗县| 岚皋县| 平舆县| 建湖县| 吕梁市| 牟定县| 高淳县| 阜宁县| 包头市| 龙江县| 天台县| 舞阳县|