缓存
缓存优势¶
- 页面秒开
- 减少服务器压力
- 无网络可用
Net缓存特点¶
- 缓存任何请求方式
- 缓存任何数据, File/图片/JSON/ProtoBuf等
- 限制最大缓存空间
- 使用
DiskLruCache
实现, 删除最近最少使用
配置缓存¶
不配置Cache
是不会启用缓存的
NetConfig.initialize(Api.HOST, this) {
// Net支持Http缓存协议和强制缓存模式
// 当超过maxSize最大值会根据最近最少使用算法清除缓存来限制缓存大小
cache(Cache(cacheDir, 1024 * 1024 * 128))
}
判断响应来自缓存
如果Response.cacheResponse
不为null的时, 代表Response来自本地缓存
Http缓存协议¶
OkHttp默认的Http缓存协议控制, 要求以下条件
- Get请求方式
- 缓存使用Url为key, 因此Url改变会读不到缓存
- 响应头控制缓存: Cache-Control
通过setCacheControl
可以控制Http缓存协议, 原理是修改请求头
scopeNetLife {
Post<String>(Api.PATH) {
setCacheControl(CacheControl.FORCE_CACHE) // 强制使用缓存
// setCacheControl(CacheControl.FORCE_NETWORK) // 强制使用网络
// setCacheControl(CacheControl.Builder().noStore().noCache().build()) // 禁止缓存
}.await()
}
如果无法实现Http标准缓存协议, 或要缓存Get以外的请求方法, 可以使用强制缓存模式
强制缓存模式¶
无论当前请求是否存在Http标准缓存协议, 当设置强制缓存模式时会无视Http缓存协议
scopeNetLife {
tv.text =
Post<String>(Api.PATH) {
setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
}.await()
}
强制缓存模式 | 描述 |
---|---|
READ | 只读取缓存, 读不到NoCacheException |
WRITE | 只请求网络, 强制写入缓存 |
READ_THEN_REQUEST | 先从缓存读取,如果失败再从网络读取, 强制写入缓存 |
REQUEST_THEN_READ | 先从网络读取,如果失败再从缓存读取, 强制写入缓存 |
自定缓存Key¶
仅强制缓存模式
有效, 缓存Key默认是请求方式+URL
后产生的sha1值
如果要缓存区别请求参数, 请自定义缓存key
scopeNetLife {
tv.text =
Post<String>(Api.PATH) {
setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
setCacheKey("请求热门信息" + params) // 具体值都行
}.await()
}
缓存有效期¶
- 仅
强制缓存模式
有效, 标准Http缓存协议遵守协议本身的有效期 - 缓存有效期过期只是让缓存无效, 不会立即删除
根据(最近最少使用)原则在缓存空间达到配置值时删除(即使缓存有效期未到)
scopeNetLife {
tv.text =
Post<String>(Api.PATH) {
setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
setCacheValidTime(1, TimeUnit.DAYS) // 缓存仅一天内有效
}.await()
}
预览(缓存+网络)¶
预览又可以理解为回退请求, 一般用于秒开首页或者回退加载数据
scopeNetLife {
// 然后执行这里(网络请求)
tv.text = Get<String>(Api.PATH) {
setCacheMode(CacheMode.WRITE)
}.await()
Log.d("日志", "网络请求")
}.preview {
// 先执行这里(仅读缓存), 任何异常都视为读取缓存失败
tv.text = Get<String>(Api.PATH) {
setCacheMode(CacheMode.READ)
}.await()
Log.d("日志", "读取缓存")
}
预览和加载两次有什么区别?
区别是preview
可以控制以下行为
breakError
读取缓存成功后不再处理请求的错误, 默认falsebreakLoading
读取缓存成功后立刻结束加载动画, 默认true