我们在做网络请求的时候,如果网络请求过于频繁而且请求的数据变动不大,或者基本没有变动,这个时候如果没有缓存功能,我们想一下
会浪费掉多少资源,一次请求刷新一次,去请求一次,不但会消耗用户的流量,而且还对服务端造成不必要的网络压力(当然如果服务器牛逼那么无所谓(*^__^*) )
所以除了自己做缓存以外okhttp自己也有一套缓存的机制
那就是继承Interceptor接口
我们先下okhttp中 Interceptor的介绍
/** * Observes, modifies, and potentially short-circuits requests going out and the corresponding * responses coming back in. Typically interceptors add, remove, or transform headers on the request * or response. */
他的大概意思就是 观察,修改,并且使相应的请求走出去,通常添加这个拦截器去添加,移除,或者转换这个请求或者返回的的header 头部信息。
所以这个拦截器的作用就是去修改请求或者返回的头部信息。
那么为什么修改头部信息的拦截器就能做到缓存呢?
我们先看一个包含首部的Http Entry
http://google.com/foo GET 2 Accept-Language: fr-CA Accept-Charset: UTF-8 HTTP/1.1 200 OK 3 Content-Type: image/png Content-Length: 100 Cache-Control: max-age=600
可以看到头部信息有一个Cache-Control缓存控制
我们可以通过设置这个对Http请求进行缓存设置
下面直接看这个类吧(非自己编写,但是忘了作者的地址)
public class CacheInterceptor implements Interceptor { private Context mContext; @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request();//获取请求 //这里就是说判读我们的网络条件,要是有网络的话我么就直接获取网络上面的数据,要是没有网络的话我么就去缓存里面取数据 if(Utils.GetConnectType(mContext) == Constant.NetworkStatus.DisConnect){ request = request.newBuilder() //这么写就是只从缓存取 .cacheControl(CacheControl.FORCE_CACHE) .build(); LogUtils.v("CacheInterceptor","no network""); } Response orginalResponse = chain.proceed(request); //有网络的条件下 if(Utils.GetConnectType(mContext) != Constant.NetworkStatus.DisConnect){ String cacheControl = request.cacheControl().toString(); return orginalResponse.newBuilder() //这里设置的为0就是说不进行缓存,我们也可以设置缓存时间 .header("Cache-Control", "public, max-age=" + 0) .removeHeader("Pragma") .build(); }else{ int maxTime = 4*24*60*60; return orginalResponse.newBuilder() //这里的设置的是我们的没有网络的缓存时间,想设置多少就是多少。 .header("Cache-Control", "public, only-if-cached, max-stale="+maxTime) .removeHeader("Pragma") .build(); } } public CacheInterceptor(Context context){ this.mContext = context; } }
类里面分别对无网络情况,和有网络情况进行了一个区分,无网络情况下我们在缓存中取,有网络条件下直接进行请求并且还可以设置缓存时间