Retrofit2缓存实现
Posted sanxiandoupi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Retrofit2缓存实现相关的知识,希望对你有一定的参考价值。
为什么使用缓存
1.提高加载速度
2.减少流量消耗
3.减轻服务端压力
4.没有网络时可以同样访问,优化用户体验
说说我的需求:
1.有网的时候使用缓存较短时间,及时更新,没有网的时候缓存更长时间
2.指定的接口产生缓存文件,其他接口不会产生缓存文件
3.可通过下拉刷新强制刷新
实现原理
Retrofit2实现缓存自然是通过okhttp拦截器实现,具体则是由Cache-Control控制
分别如下:
1 2 3 4 5 6 7 8 9 10 11 12
| no-cache no-cache是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。 no-store 所有内容都不会被缓存到缓存或 Internet 临时文件中 max-age=xxx (xxx is numeric) 缓存的内容将在 xxx 秒后失效, 这个选项只在HTTP 1.1可用, 并如果和Last-Modified一起使用时, 优先级较高 max-stale和max-age一样,只能设置在请求头里面。 同时设置max-stale和max-age,缓存失效的时间按最长的算。(这个其实不用纠结) CacheControl.FORCE_CACHE 强制使用缓存,如果没有缓存数据,则抛出504(only-if-cached) CacheControl.FORCE_NETWORK 强制使用网络,不使用任何缓存.
|
简单实现
1.先要创建拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| static Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() { public Response (Chain chain) throws IOException { Request request = chain.request(); Response response = chain.proceed(request); if (NetworkUtil.isNetworkAvalible(MyApplication.getContext())) { int maxAge = 60; return response.newBuilder() .removeHeader("Pragma") .header("Cache-Control", "public ,max-age=" + maxAge) .build(); } return response; } };
|
2.这样的话就写好了拦截器,然后就是把拦截器设置到okhttp里面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| File httpCacheDirectory = new File(MyApplication.getInstance().getExternalCacheDir(), "HttpCache"); 大专栏 Retrofit2缓存实现 class="attribute"> int cacheSize = 10 * 1024 * 1024; Cache cache = new Cache(httpCacheDirectory, cacheSize); OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(15, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR) .cache(cache) .build(); retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build();
|
注意缓存路径要写对,同时注意addNetworkInterceptor和addInterceptor的区别
这样就简单实现了retrofit的缓存,在60秒内可以通过缓存来访问,优化访问速度与体验
不同接口可缓存不同时间,同时可设置是否缓存
从header中获取cache-Control字段,即可实现不同接口缓存不同时间,header中没有cache-control字段时则不缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Headers("Cache-Control: public, max-age=3600") @GET("song/getsonglistsong?id=recommend") Flowable<SongList> getRecommendList(); static Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() { public Response (Chain chain) throws IOException { Request request = chain.request(); Response response = chain.proceed(request); if (NetworkUtil.isNetworkAvalible(MyApplication.getContext())) { String cacheControl =request.cacheControl().toString(); return response.newBuilder() .removeHeader("Pragma") .header("Cache-Control", cacheControl) .build(); } return response; } };
|
参考链接
https://www.cnblogs.com/cxk1995/p/5996586.html
https://blog.csdn.net/adzcsx2/article/details/51365548
https://www.jianshu.com/p/241e6af94390
https://blog.csdn.net/wangkeke1860/article/details/52084869
https://www.jianshu.com/p/9c3b4ea108a7
https://www.cnblogs.com/android-yus/p/5280739.html
https://blog.csdn.net/u010286855/article/details/52608485
以上是关于Retrofit2缓存实现的主要内容,如果未能解决你的问题,请参考以下文章
Android 使用Retrofit2.0+OkHttp3.0实现缓存处理+Cookie持久化第三方库
一款基于RxJava2+Retrofit2实现简单易用的网络请求框架
Retrofit2 和 OkHttp3 仅在发生错误时使用缓存,例如网络错误或达到配额限制
使用Retrofit2解析XML。多个结果列表不起作用
如何缓存片段视图
导航到另一个片段时触发 API 调用