Browse Source

新增强制缓存有效期

drake 3 years ago
parent
commit
7b0b3ff53b

+ 1 - 1
README.md

@@ -65,7 +65,7 @@ Net 3.x 版本使用OkHttp+协程实现, 可指定其OkHttp版本
 - 全局取消请求/自动取消请求
 - Https快速配置
 - Cookie持久化管理
-- 强制缓存模式/自定义缓存Key/LRU缓存算法/缓存任何类型
+- 强制缓存模式/自定义缓存Key/缓存有效期/LRU缓存算法/缓存任何数据
 - 缓存+网络双重读取(预览模式实现)
 - 内置超强轮询器(计时器)
 - 监听上传/下载进度(使用时间, 每秒速度, 剩余时间...)

+ 32 - 4
docs/cache.md

@@ -51,9 +51,6 @@ scopeNetLife {
     binding.tvFragment.text =
         Post<String>("api") {
             setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
-            // setCacheKey("自定义缓存KEY")
-            // 通过自定义Key可以设置一个每天会失效的缓存. 但超出缓存限制后还是会遵守最近最少使用删除策略
-            // setCacheKey("自定义缓存KEY" + System.currentTimeMillis() / TimeUnit.DAYS.toMillis(1))
         }.await()
 }
 ```
@@ -67,7 +64,38 @@ scopeNetLife {
 | READ_THEN_REQUEST | 先从缓存读取,如果失败再从网络读取, 强制写入缓存 |
 | REQUEST_THEN_READ | 先从网络读取,如果失败再从缓存读取, 强制写入缓存 |
 
-> 在okHttp中`response.cacheResponse`不为null的时候即代表response来自于本地缓存, 强制缓存或Http缓存协议都如此
+> 如果`response.cacheResponse`不为null的时候即代表response来自于本地缓存, 强制缓存或Http缓存协议都如此
+
+
+## 自定缓存Key
+
+缓存Key默认是`请求方式+URL`后产生的sha1值, 所以并不会使用请求参数判断(综合考虑都不适用)
+
+如果你要实现区别请求参数的缓存请自定义缓存key, 如下
+
+```kotlin
+scopeNetLife {
+    binding.tvFragment.text =
+        Post<String>("api") {
+            setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
+            setCacheKey("请求热门信息" + params) // 具体值都行
+        }.await()
+}
+```
+
+## 缓存有效期
+
+缓存有效期只针对`强制缓存模式`, 标准Http缓存协议遵守协议本身的有效期
+
+```kotlin
+scopeNetLife {
+    binding.tvFragment.text =
+        Post<String>("api") {
+            setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
+            setCacheValidTime(1, TimeUnit.DAYS) // 缓存仅一天内有效
+        }.await()
+}
+```
 
 ## 缓存+网络
 

+ 7 - 1
net/src/main/java/com/drake/net/cache/ForceCache.kt

@@ -159,7 +159,13 @@ class ForceCache internal constructor(
         }
 
         if (!entry.matches(request)) return null
-        return entry.response(snapshot, request.body)
+        val response = entry.response(snapshot, request.body)
+        val value = request.tagOf<NetTag.CacheValidTime>()?.value
+        return if (value != null && System.currentTimeMillis() - response.receivedResponseAtMillis > value) {
+            null
+        } else {
+            response
+        }
     }
 
     internal fun put(response: Response): Response {

+ 13 - 0
net/src/main/java/com/drake/net/request/BaseRequest.kt

@@ -31,6 +31,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
 import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import java.io.File
 import java.net.URL
+import java.util.concurrent.TimeUnit
 import kotlin.reflect.typeOf
 
 abstract class BaseRequest {
@@ -294,6 +295,18 @@ abstract class BaseRequest {
     fun setCacheKey(key: String) {
         tagOf(NetTag.CacheKey(key))
     }
+
+    /**
+     * 强制缓存有效期
+     * 注意即使缓存有效期很长也无法阻止LRU最近最少使用算法清除超出缓存最大限制
+     *
+     * 标准Http缓存协议遵守协议本身的有效期, 当前方法配置无效
+     * @param duration 持续时间
+     * @param unit 时间单位, 默认毫秒
+     */
+    fun setCacheValidTime(duration: Long, unit: TimeUnit = TimeUnit.MILLISECONDS) {
+        tagOf(NetTag.CacheValidTime(unit.toMillis(duration)))
+    }
     //</editor-fold>
 
     //<editor-fold desc="Download">

+ 3 - 0
net/src/main/java/com/drake/net/tag/NetTag.kt

@@ -53,6 +53,9 @@ sealed class NetTag {
     @JvmInline
     value class CacheKey(val value: String)
 
+    @JvmInline
+    value class CacheValidTime(val value: Long)
+
     @JvmInline
     value class DownloadFileDir(val value: String) {
         constructor(fileDir: File) : this(fileDir.absolutePath)

+ 0 - 2
sample/src/main/java/com/drake/net/sample/ui/fragment/ReadCacheFragment.kt

@@ -37,8 +37,6 @@ class ReadCacheFragment : EngineFragment<FragmentReadCacheBinding>(R.layout.frag
                 Post<String>("api") {
                     setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
                     // setCacheKey("自定义缓存KEY")
-                    // 通过自定义Key可以设置一个每天会失效的缓存. 但超出缓存限制后还是会遵守最近最少使用删除策略
-                    // setCacheKey("自定义缓存KEY" + System.currentTimeMillis() / TimeUnit.DAYS.toMillis(1))
                 }.await()
         }
     }