Android Http缓存数据处理

来源:互联网 发布:好身材 知乎 编辑:程序博客网 时间:2024/06/05 10:32

来北京一个多月了~
本周做组里技术分享时,被提问到一个问题:
Retrofit里自带网络线程调度(okHttp),适配RxJava后,内部是同步还是异步的?异步的话,就多了一层线程的包装了?
听完问题后,我的第一反应是,Jake大神怎么能没处理好这个问题呢,内部肯定是选择同步了吧,使用RxJava的理念就是线程调度都交给Rx好了。
但我确实没有看过这部分源码……当时只对动态代理感兴趣了……配合RxJava使用是随即开始了……
今天跑到公司,看了下源码,CallAdapter的处理,确实是同步的:)
真希望组里能用上Rx,太不喜欢现在的代码结构了。


还看到了这篇文章:
http://www.jianshu.com/p/07dac989272c
里面讲到了Volly对缓存提供了贴心的ttl和softTtl:

缓存处理;Volley自己就提供了一套完整的缓存处理方案,默认使用文件存储到磁盘中,并且提供了TTL
SOFTTTL这么体贴入微的机制;一个Request可能存在两个Response,对于需要显示缓存,再显示网络数据的场景真是爽的不要不要的。而Retrofit中并没有提供任何和缓存相关的方案

我都不好意思说自己曾经也看过Volly源码了,也用了Volly半年多……我确实没注意过

这个功能确实太好用了
只要没超期,那Volley去请求URL会先返回缓存的结果,再返回网络结果
我记得okHttp对缓存处理是没有这样的过程的,它就是按照协议去做了。

现在的代码里都是自己存缓存。取数据时,自己先读缓存(也是文件形式),再读网络。
而Volly其实已经做好了。max-age设成极大值,就可以让缓存长时间有效了。
Volly貌似已经成为明日黄花了,但还是要再分析下源码,经典源码太多值得学的地方了。

Http协议里CacheControl有两个字段表达响应的过期时间:max-age和max-stale
前者表示:max-age秒内,网页再有请求,你不要来我服务端,直接取你本地缓存的结果好了
后者表示:max-stale秒内的请求,你可以使用本地缓存的,但还是要来我服务端问问,到底行不行,当然,这里要带上Last Modified等信息
如果服务端返回了304,那说明你本地缓存继续用吧,我不给你响应体
200的话,自然就带上了响应体。

先看CacheDispather.java, 注意里面的英文注释

    if (!entry.refreshNeeded()) {                    // Completely unexpired cache hit. Just deliver the response.                    mDelivery.postResponse(request, response);                } else {                    // Soft-expired cache hit. We can deliver the cached response,                    // but we need to also send the request to the network for                    // refreshing.                    request.addMarker("cache-hit-refresh-needed");                    request.setCacheEntry(entry);                    // Mark the response as intermediate.                    response.intermediate = true;                    // Post the intermediate response back to the user and have                    // the delivery then forward the request along to the network.                    mDelivery.postResponse(request, response, new Runnable() {                        @Override                        public void run() {                            try {                                mNetworkQueue.put(request);                            } catch (InterruptedException e) {                                // Not much we can do about this.                            }                        }                    });                }            }

再看一下cache.entry的构造,注意softExpire 和finalExpire

  // Cache-Control takes precedence over an Expires header, even if both exist and Expires        // is more restrictive.        if (hasCacheControl) {            softExpire = now + maxAge * 1000;            finalExpire = mustRevalidate                    ? softExpire                    : softExpire + staleWhileRevalidate * 1000;        } else if (serverDate > 0 && serverExpires >= serverDate) {            // Default semantic for Expire header in HTTP specification is softExpire.            softExpire = now + (serverExpires - serverDate);            finalExpire = softExpire;        }

codeKK上有对Volley源码分析
http://a.codekk.com/detail/Android/grumoon/Volley%20%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90

再补一张图(来源)
这里写图片描述

原作者写到试图让Retrofit支持这样的功能,但没有下文。
我试了下,首先拦截器没法实现这个功能,在ok对缓存里的处理里也不行,只能在回调结果处实现?
okHttp里AsyncCall里execute

 @Override protected void execute() {      boolean signalledCallback = false;      try {        Response response = getResponseWithInterceptorChain(forWebSocket);        if (canceled) {          signalledCallback = true;          responseCallback.onFailure(originalRequest, new IOException("Canceled"));        } else {          signalledCallback = true;          responseCallback.onResponse(response);        }      } catch (IOException e) {        if (signalledCallback) {          // Do not signal the callback twice!          logger.log(Level.INFO, "Callback failure for " + toLoggableString(), e);        } else {          Request request = engine == null ? originalRequest : engine.getRequest();          responseCallback.onFailure(request, e);        }      } finally {        client.dispatcher().finished(this);      }    }  }

在这里先去缓存拿一个结果,回调下onResponse,再实际去网络,再onResponse

怎么把Volly那套移植呢

再想想 :)

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 确认收货点错了怎么办 小米6后盖缝隙大怎么办 苹果6splus电池不耐用怎么办 苹果一朵云加箭头下载不了怎么办 苹果8p信号不好怎么办 苹果8p像素不好怎么办 美版iphonex有锁怎么办 苹果8x突然黑屏怎么办 苹果6s无法激活怎么办 苹果6sp激活出错怎么办 小米4c触屏失灵怎么办 手机谷歌浏览器为什么打不开怎么办 谷歌浏览器打不开网址怎么办 拼多多被限制了怎么办 保时捷11年的前机盖打不开怎么办 唯品会衣服质量有问题怎么办 唯品会买的东西有质量问题怎么办 唯品会上卖到假东西怎么办 个人资金链断了怎么办 腾讯财理通平台倒闭投资者该怎么办 ebay买到假货了怎么办 善心汇会员被限制出行怎么办 苹果手机屏碎了怎么办 三国志2017仓库满了怎么办 至尊宝密保手机被改了怎么办 电脑版qq游戏途中死机怎么办 登陆企业qq服务器超时怎么办 qq登录不上怎么办错误00001 苹果手机白屏进不了界面怎么办 苹果8p手机白屏怎么办 苹果5s无法关机怎么办 三星手机白屏了怎么办 电脑能上qq打不开网页怎么办? 电脑打不开机怎么办黑屏 英雄杀连接不上怎么办 炫舞时登陆器卸下载失败怎么办 电视为什么会出现登录超时怎么办 登录app时提示请求超时怎么办 手机来短信断网怎么办 百度网络不给力怎么办 网络连接不给力怎么办