概述
- Retrofit本身是沒有緩存的,如果想設(shè)置緩存功能,需要在http client層知道HTTP的語義。
- okhttp是square公司發(fā)布的一個HTTP client,它支持高速緩存服務(wù)器響應(yīng)的語義。
- 使用場景:提高用戶體驗,降低服務(wù)器的負(fù)荷。無網(wǎng)絡(luò)的條件下,讀取緩存;有網(wǎng)條件下,對非實時性的數(shù)據(jù)可以在規(guī)定的時間里讀取緩存,例如設(shè)置時間為60s,實時性的數(shù)據(jù)還是要每次都獲取最新數(shù)據(jù)。
封裝Retrofit管理類
public class RetrofitManger {
private static RetrofitManger mInstance;
public static boolean isDebug = false;
public static synchronized RetrofitManger getInstance() {
if (mInstance == null)
mInstance = new RetrofitManger();
return mInstance;
}
public void deBug(boolean isDebug) {
this.isDebug = isDebug;
}
// create retrofit singleton
private Retrofit createApiClient(String baseUrl) {
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(createOkHttpClient(isDebug))
.build();
}
// create okHttpClient singleton
OkHttpClient createOkHttpClient(boolean debug) {
//設(shè)置緩存100M
Cache cache = new Cache(new File(MainApplication.getContext().getCacheDir(),"httpCache"),1024 * 1024 * 100);
return new OkHttpClient.Builder()
.cache(cache)
.addNetworkInterceptor(new HttpCacheInterceptor())
.addInterceptor(
new HttpLoggingInterceptor().setLevel(
debug ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE))
.build();
}
}
HttpCacheInterceptor類
public class HttpCacheInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!NetWorkHelper.isNetConnected(MainApplication.getContext())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (NetWorkHelper.isNetConnected(MainApplication.getContext())) {
int maxAge = 60; // read from cache for 1 minute
response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
return response;
}
}
有網(wǎng)絡(luò)的情況下設(shè)置max-age=60,即1分鐘;沒有網(wǎng)絡(luò)的情況下設(shè)置max-stale=60 x 60 x 24 x 28,即4周。
okhttp3 中Cache類包含的緩存策略
noCache :不使用緩存,全部走網(wǎng)絡(luò)
noStore : 不使用緩存,也不存儲緩存
onlyIfCached : 只使用緩存
maxAge :設(shè)置最大失效時間,失效則不使用
maxStale :設(shè)置最大失效時間,失效則不使用
minFresh :設(shè)置最小有效時間,失效則不使用
FORCE_NETWORK : 強制走網(wǎng)絡(luò)
FORCE_CACHE :強制走緩存
單個接口設(shè)置緩存
上面介紹的都是統(tǒng)一設(shè)置緩存,Retrofit還可以為單個接口設(shè)置緩存。
配置單個請求的@Headers,設(shè)置此請求的緩存策略不影響其他請求的緩存策略,不設(shè)置則沒有緩存。
// 設(shè)置單個請求的緩存時間
@Headers("Cache-Control: max-age=640000")
@GET("user/list")
Call<List<javaBean>> getList();
讀取單個接口的@Headers配置
String cacheControl = request.cacheControl().toString();
response.newBuilder()
.header("Cache-Control", cacheControl)
.removeHeader("Pragma")
.build();