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那套移植呢
再想想 :)
- Android Http缓存数据处理
- Android Volley http缓存
- http缓存Android
- Android Http RequestCache缓存策略
- Android 4.0 Http缓存机制
- java/android http数据缓存
- 关于浏览器缓存数据处理
- Android 4.0 设置Http缓存的方式
- android--http请求及缓存框架GalHttprequest
- 当Android遇见HTTP缓存代理服务器
- Android HTTP请求下载图片并缓存
- Http缓存
- http缓存
- http缓存
- HTTP缓存
- Http缓存
- HTTP缓存
- http缓存
- XPath与多线程爬虫
- xargs命令详解
- GraphX创建图并可视化的核心技术
- XML(5)序列化写入xml文件
- 《剑指offer》:[15]实现指数函数:x的y次方
- Android Http缓存数据处理
- 【Linux】Linux系统下进度条的模拟实现
- Android-menu
- Python内置函数chr() unichr() ord()
- 原来我一个对网络不熟的人,也可以通过网络盈利,神了
- 【C++学习笔记】
- 移除监听事件
- Cannot launch AVD in emulator. Output: sh: 1: glxinfo:
- OC&&IOS开发小技巧总结