91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

okhttp3.4.1+retrofit2.1.0如何實現離線緩存

發布時間:2021-07-26 13:49:57 來源:億速云 閱讀:162 作者:小新 欄目:移動開發

這篇文章將為大家詳細講解有關okhttp3.4.1+retrofit2.1.0如何實現離線緩存,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

即有網環境下我們請求數據時,如果沒有緩存或者緩存過期了,就去服務器拿數據,并且將新緩存保存下來,如果有緩存而且沒有過期,則直接使用緩存。無網環境下我們請求數據時,緩存沒過期則直接使用緩存,緩存過期了則無法使用,需要重新聯網獲取服務器數據。

緩存處理還是很有必要的,它有效的減少服務器負荷,降低延遲提升用戶體驗,同時也方便用戶即使在沒網絡的情況下也能使用APP。

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

一、添加依賴

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(設置緩存路徑和緩存文件大小)

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

三、配置Retrofit

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

四、編寫攔截器

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

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

到這里,其實已經可以實現了我們開頭所說的緩存效果了。

但是,上面設置的每個接口緩存時間都一樣,例如我現在想讓不同接口的緩存數據失效時間都不一樣,甚至有些接口不緩存數據,應該怎么做呢?其實也很簡單

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

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

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

 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")//清除頭信息,因為服務器如果不支持,會返回一些干擾信息,不清除下面無法生效
      .header("Cache-Control", cacheControl)
      .build();
   }
   return response;
  }
 };

*注意:

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

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

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

附上所有代碼:

/**
 * 簡單封裝的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)//設置連接超時
    .readTimeout(10, TimeUnit.SECONDS)//讀取超時
    .writeTimeout(10, TimeUnit.SECONDS)//寫入超時
    .addInterceptor(interceptor)//添加日志攔截器
    .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)//添加緩存攔截器
    .cache(cache)//把緩存添加進來
    .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")//清除頭信息,因為服務器如果不支持,會返回一些干擾信息,不清除下面無法生效
//      .header("Cache-Control", cacheControl)
//      .build();
//   }
//   return response;
//  }
// };
 //緩存攔截器,統一緩存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;//緩存失效時間,單位為秒
    return response.newBuilder()
      .removeHeader("Pragma")//清除頭信息,因為服務器如果不支持,會返回一些干擾信息,不清除下面無法生效
      .header("Cache-Control", "public ,max-age=" + maxAge)
      .build();
   }
   return response;
  }
 };
}

關于“okhttp3.4.1+retrofit2.1.0如何實現離線緩存”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

海林市| 武城县| 尤溪县| 阿图什市| 邳州市| 德阳市| 辽阳县| 佛坪县| 洮南市| 磐石市| 新宁县| 和顺县| 平舆县| 新安县| 盐边县| 娄底市| 宁都县| 枝江市| 桐乡市| 曲沃县| 南和县| 马关县| 上思县| 长岭县| 杭锦旗| 大渡口区| 雅安市| 拜泉县| 镇宁| 洛阳市| 连州市| 沁源县| 来宾市| 临潭县| 东辽县| 沈丘县| 巴里| 内黄县| 太谷县| 阿拉善右旗| 昌乐县|