搜索
您的当前位置:首页正文

okhttp的缓存是如何工作的

来源:二三娱乐
TIM截图20191101212413.png
先放一张图,这是不考虑离线情况下的okhttp缓存工作流程图:
1_X8clb2gjCfTtlf2B7HU6Tw.png
okhttp的缓存是基于http协议的,也就是,假如服务器返回的http header里表明了是不支持cache的,比如这样
image_2019-10-24_18-34-25.png

1. 如何启用okhttp的缓存?

只需要一句代码就够了:

int cacheSize = 10 * 1024 * 1024; // 10MB
OkHttpClient.Builder builder = new OkHttpClient.Builder()
        .cache(new Cache(context.getCacheDir(), cacheSize) 

2. 如何让okhttp的缓存工作?

Date:Wed, 29 Mar 2017 10:54:09 GMT
ETag:"82ccabc2f791cdd2217922e2f362bb4f:1490757927"
Last-Modified:Wed, 29 Mar 2017 03:25:27 GMT
If-Modified-Since:Wed, 29 Mar 2017 03:25:27 GMT
If-None-Match:"82ccabc2f791cdd2217922e2f362bb4f:1490757927"

3. 如何使用离线缓存?

new Request.Builder().cacheControl(CacheControl.FORCE_CACHE)

1_zJp2xmQMR00OihsEVE0ONw.png

如果你一定要在没有网的情况下,使用缓存,那么你可以这样写

public class ForceCacheInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request.Builder builder = chain.request().newBuilder();
        if (!NetworkUtils.internetAvailable()) {
            builder.cacheControl(CacheControl.FORCE_CACHE);
        }
        
        return chain.proceed(builder.build());
    }
}
okHttpClient.addInterceptor(new ForceCacheInterceptor());

4. 使用okhttp的缓存策略来存储数据是一个good idea吗?我们只需要设置FORCE_CACHE,然后我们就总能获取到存储的数据

It’s a bad idea。这根本是两个概念,应该区别对待。文章在这里提到,token应该被存储,而诸如新闻之类的东西才应该被缓存。文章的意思是缓存和存储是完全不同的两个概念,其实这也很好理解。停一下,喝杯咖啡思考一下~

5. 如何确定我们是否需要服务器来校验缓存?

For example, you are refreshing your Facebook setting page which has a list of settings. So, that list should stay unchanged for quite sometimes. So instead of return the same response every time, the server can just say max-age=3600 and for all the subsequence requests in the next 1 hour (3600 seconds), the client can just use the local cached data.

上面这一段是文章中的原话,大致是说,例如脸书设置页面的一些list,短时间内不会更改的,可以考虑设置一个小时的cache 时间。但这是2017年的文章了,我在最新的脸书的设置页面里,没见到类似的需要服务器返回的列表页。总之,通过这个例子理解max-age的用处就可以了。

6. 服务器是如何确定客户端是否应该使用缓存的?

One example is the Gmail app, because the client has no way to know if there are new emails every time the user refreshes, so it can’t just simply use the cached data. What it always does is to send out the last Etag to tell the server what was the last time the user checked their inbox. Then if there is no new email, the server just tells the client to use its cache to display the same email list.

上面这段话也是原文里的,我就不一句一句翻译了。大致是说,以gmail为例,可以通过每次请求时带上Etag,然后服务器就知道该不该返回新的数据给客户端,客户端也知道该不该使用缓存了。

文章到这里也就完了,感兴趣的点击最开始的链接阅读原文。我个人认为这篇文章是讲okhttp缓存讲的比较好的。在翻译过程中,我也加了一些自己的想法,如果觉得我有翻译错误的地方,也欢迎在评论区指出。

Top