简体   繁体   English

修改Retrofit/OkHttp缓存满时的处理逻辑?

[英]Modify logic of what to do when cache is full in Retrofit/OkHttp?

I am trying to define my own logic of how is cache handled when it is full, because actual behavior is not wanted.我正在尝试定义我自己的缓存满时如何处理的逻辑,因为不需要实际行为。 I do not know if it is possible (I have not found any documentation on this topic), so I am asking here.我不知道这是否可能(我还没有找到关于这个主题的任何文档),所以我在这里问。

When cache is full, Retrofit/OkHttp is removing cached responses based on their validity duration, prioritizing these, that expire sooner.当缓存已满时,Retrofit/OkHttp 将根据其有效期删除缓存的响应,优先考虑这些响应,这些响应会更快过期。

Simple example:简单的例子:

If we have an empty cache of for example 1MB and there comes response of size 700KB that expires in 1 hour (Cache-Control: max-age=3600) and after this comes different response of size 800KB (it does not fit in cache anymore) that expires in 30 minutes, the second response is not cached.如果我们有一个例如 1MB 的空缓存,并且响应大小为 700KB,在 1 小时内过期(缓存控制:max-age=3600),然后是大小为 800KB 的不同响应(它不再适合缓存) 在 30 分钟后过期,则不会缓存第二个响应。

Another example:另一个例子:

In 1MB cache we have 800KB response that expires in 1 hour from now and then another response comes that have 800KB that expires in 5 hours.在 1MB 缓存中,我们有 800KB 响应在 1 小时后过期,然后另一个响应有 800KB 在 5 小时后过期。 The 1 hour response is removed and 5 hour response is stored.删除 1 小时响应并存储 5 小时响应。

I want to change this behavior, to be that responses are removed from cache based on their receival time (OkHttp-Received-Millis attribute), not their expiration time, so oldest reponses are removed first.我想更改此行为,即根据接收时间(OkHttp-Received-Millis 属性)而不是过期时间从缓存中删除响应,因此首先删除最旧的响应。

Creation of http client and retrofit initialization:创建 http 客户端和 retrofit 初始化:

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);
}

Structure of cached response call:缓存响应调用的结构:

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

One more time, actual behavior is that responses are removed from cache (when its full) based on calculation time now + max-age (lowest are removed first) and wanted behavior is that oldest are removed, based on OkHttp-Received-Millis .还有一次,实际行为是根据现在的计算时间+ max-age (首先删除最低的)从缓存中删除响应(当它已满时),而想要的行为是根据OkHttp-Received-Millis删除最旧的。

Is something like this possible to do?这样的事情可能吗?

OkHttp's cache evicts the least-recently used items. OkHttp 的缓存会驱逐最近最少使用的项目。 It does not consider when an item'a freshness time when making eviction decisions.在做出驱逐决定时,它不考虑一个项目的新鲜时间。

There is no API to change this policy.没有 API 可以更改此策略。 If you'd like to manually evict items from the cache, you may use the cache's iterator and call remove on the items you decide should be evicted.如果您想手动从缓存中逐出项目,您可以使用缓存的iterator并在您决定应该被逐出的项目上调用remove

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM