okhttp之自定义Interceptor:缓存拦截器

尊重他人的劳动成果,转载请标明出处:http://blog.csdn.net/gengqiquan/article/details/52200638, 本文出自:【gengqiquan的博客】

新公司项目是没有缓存的,我的天,坑用户流量不是么。不知道有人就喜欢一个界面没事点来点去的么。怎么办?一个字“加”。
由于项目的网络请求被我换成了retrofit。而retrofit的网络请求默认基于okhttp
okhttp的缓存由返回的header 来决定。如果服务器支持缓存的话返回的headers里面会有这一句

Cache-Control”,“max-age=time”

这里的time是一个单位为秒的时间长度。意思是缓存的时效,比如要设置这个API的缓存时效为一天
返回的header就应该是

Cache-Control”,“max-age=3600*24

不巧。公司的服务器不支持缓存的,怎么看出来的?因为我们的返回的headers是包含这些的

这里写图片描述

但我们又想用缓存,这个时候怎么办呢。,得益于okhttp的Interceptor机制,一切的配置都可以变得那么简单优雅。
我们可以在拦截器里截获headers然后移除默认的Cache-Control

但是我们知道有些API返回的数据适合缓存,而有些是不适合的,比如资讯列表,各种更新频率比较高的,是不可以缓存的,而像资讯详情这种数据是可以缓存的。所以我们不能直接统一写死。需要动态配置。

同样的,我们也在header里面作文章,自定义一个header。注意这个header一定不能被其他地方使用,不然会被覆盖值。这里我们定义的header的key名字为:Cache-Time。我们在拦截器里去取这个header。如果取得了不为空的值,说明这个请求是要支持缓存的,缓存的时间就是Cache-Time对应的值。我们把他添加进去。
自定义缓存Interceptor

public class CacheInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        String cache = request.header("Cache-Time");
        if (!Util.checkNULL(cache)) {//缓存时间不为空
            Response response1 = response.newBuilder()
                    .removeHeader("Pragma")
                    .removeHeader("Cache-Control")
                    //cache for cache seconds
                    .header("Cache-Control", "max-age="+cache)
                    .build();
            return response1;
        } else {
            return response;
        }
    }
}

缓存拦截器定义好了,我们还需要配置缓存的路径。这里我们定义一个缓存的内容提供器

public class CacheProvide {
    Context mContext;

    public CacheProvide(Context context) {
        mContext = context;
    }

    public Cache provideCache() {//使用应用缓存文件路径,缓存大小为10MB
        return new Cache(mContext.getCacheDir(), 10240 * 1024);
    }
}

通过上面的代码我们可以看到我们指定了缓存的大小为10MB。这里如果缓存的数据量大于这个值,内部会使用lur规则进行删除。

下面我们开始配置OkHttpClient

 OkHttpClient client = new OkHttpClient.Builder()
                    .addNetworkInterceptor(new CacheInterceptor())//缓存拦截器
                    .cache(new CacheProvide(mAppliactionContext).provideCache())//缓存空间提供器
                    .connectTimeout(8, TimeUnit.SECONDS)
                    .readTimeout(5, TimeUnit.SECONDS)
                    .writeTimeout(5, TimeUnit.SECONDS)
                    .build();

好了,现在我们如果哪里需要缓存数据的话,只要在请求里添加header(“Cache-Time”,“3600*24”)就可以把当前数据缓存一天啦

我建了一个QQ群(群号:121606151),用于大家讨论交流Android技术问题,有兴趣的可以加下,大家一起进步。

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值