我在尝试定义我自己的缓存满了是如何处理的逻辑,因为实际行为是不希望的。我不知道是否可以(我没有找到任何关于这个主题的留档),所以我在这里问。
当缓存已满时,Retrofit/OkHttp会根据缓存的有效持续时间删除缓存的响应,优先考虑这些过期较早的响应。
简单的例子:
如果我们有一个空缓存,例如1MB,并且有大小为700KB的响应,在1小时内到期(Cache-Control: max-age=3600),之后出现大小为800KB的不同响应(它不再适合缓存),在30分钟内到期,第二个响应不会缓存。
另一个例子:
在1MB缓存中,我们有800KB的响应,该响应将在1小时后到期,然后另一个响应有800KB,将在5小时内到期。1小时响应被删除并存储5小时响应。
我想更改此行为,根据响应的接收时间(OkHttp-Recened-Millis属性)从缓存中删除响应,而不是它们的过期时间,因此首先删除最旧的响应。
创建超文本传输协议客户端和改造初始化:
private Retrofit retrofit(String baseUrl) {
return new Retrofit.Builder()
.baseUrl(baseUrl)
.client(cachingClient(CACHE_IDENTIFIER))
.addConverterFactory(GsonConverterFactory.create(gson()))
.build();
}
private OkHttpClient cachingClient(String identifier) {
return new OkHttpClient.Builder()
.cache(cache(identifier))
.addInterceptor(InterceptorsKt.authorizationInterceptor(Credentials.basic(USER, PASSWD)))
.build();
}
private Cache cache(String identifier) {
return new Cache(new File(context.get().getCacheDir(), identifier), CACHE_SIZE);
}
缓存响应调用的结构:
http://example.com:8754/random/hello
GET
0
HTTP/1.1 200
11
Cache-Control: max-age=2592000, immutable
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 21 Sep 2022 08:01:31 GMT
Keep-Alive: timeout=60
Connection: keep-alive
OkHttp-Sent-Millis: 1663747322078
OkHttp-Received-Millis: 1663747322254
再一次,实际行为是从缓存中删除响应(当其满时)基于计算时间现在max-age(最低的先删除)和想要的行为是最老的被删除,基于OkHttp-Recened-Millis。
像这样的事情有可能做吗?
OkHttp的缓存会逐出最近最少使用的项目。它在做出逐出决策时不考虑项目的新鲜度时间。
没有API更改此策略。如果您想手动从缓存中逐出项目,您可以使用缓存的迭代器
并对您决定应该逐出的项目调用删除
。