提问者:小点点

修改Retrofit/OkHttp中缓存满了怎么办的逻辑?


我在尝试定义我自己的缓存满了是如何处理的逻辑,因为实际行为是不希望的。我不知道是否可以(我没有找到任何关于这个主题的留档),所以我在这里问。

当缓存已满时,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。

像这样的事情有可能做吗?


共1个答案

匿名用户

OkHttp的缓存会逐出最近最少使用的项目。它在做出逐出决策时不考虑项目的新鲜度时间。

没有API更改此策略。如果您想手动从缓存中逐出项目,您可以使用缓存的迭代器并对您决定应该逐出的项目调用删除