Http Cache-Control(缓存控制)
- max-stale: 允许读取过期时间必须小于max-stale 值的缓存对象。
- max-age: 本响应包含的对象的过期时间。
- public: 数据内容皆被储存起来,就连有密码保护的网页也储存,安全性很低。
- private: 数据内容只能被储存到私有的cache,仅对某个用户有效,不能共享。
- no-cache: 可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端。
- no-store: 请求和响应都禁止被缓存。
- no-transform: 告知代理,不要更改媒体类型,比如jpg,被你改成png。
- only-if-cached:表示只接受被缓存的内容。
完成缓存,我们只需要用到上述列表中的max-age
、max-stale
以及only-if-cached
。
检查网络情况
我们希望有网的情况下从服务器拉取数据,断网状态下读缓存,或者是一下其他策略,首先我们都要判断网络状态。
<!--权限申明-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
public static final boolean isConnected() {
ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager.getActiveNetworkInfo();
return info != null && info.isConnected();
}
拦截网络请求
实现一个Interceptor
,OkHttp中可以配置请求拦截器,在请求的过程中每一条请求都会设置的所有拦截器拦截处理,在这里我们分有无网络来区别处理即可。
public final class CacheInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) {
Request request = chain.request();
Response var10000;
Response response;
if(NetworkUtils.isConneted()) {
//如果有网,返回一个30内有效的响应,则30秒内同一请求会直接从缓存中读取
response = chain.proceed(request);
//构建maxAge = 30秒的CacheControl
String cacheControl = CacheControl.Builder()
.maxAge(30, TimeUnit.SECONDS)
.build()
.toString();
var10000 = response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
//填入30秒的CacheControl
.header("Cache-Control", cacheControl)
.build();
} else {
//如果没网,用原来的请求重新构建一个强制从缓存中读取的请求
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
var10000 = chain.proceed(request);
}
return var10000;
}
}
文章一开始说用到max-age
、max-stale
以及only-if-cached
,但是在上面的代码中只看见了第一个,那么剩下的两个在哪呢?可以看见,没网的状态下我们把请求的缓存控制设置为CacheControl.FORCE_CACHE
,这个是OkHttp提供的几种CacheControl
之一,具体是这样的:
/**
* Cache control request directives that uses the cache only, even if the cached response is
* stale. If the response isn't available in the cache or requires server validation, the call
* will fail with a {@code 504 Unsatisfiable Request}.
*/
public static final CacheControl FORCE_CACHE = new Builder()
.onlyIfCached()
.maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
.build();
他这里就设置了only-if-cached
和max-stale
,只接受过期时间小于Integer.MAX_VALUE
的缓存,将秒转换成年,也就是:
2147483647秒(s)=68.0962598年(yr)
一辈子有效??
缓存地址
long size = 1024*1024*8;//缓存大小为8Mb
Cache chche = new Cache(new File(context.getCacheDir(), "a"), size);
注:getCacheDir() —– /data/data/cn.xxx.xxx(当前包)/cache
装载
OkHttpClient client
= OkHttpClient
.Builder()
.cache(cache)
.addInterceptor((Interceptor)(new CacheInterceptor()))
.addNetworkInterceptor((Interceptor)(new CacheInterceptor()))
.build();
到这里,缓存就配置好了,说的不对请指正。