Skip to main content

缓存

OkHttp实现了一个可选的、默认关闭的缓存 Cache

基本使用

private val client: OkHttpClient = OkHttpClient.Builder()
.cache(Cache(
directory = File(application.cacheDir, "http_cache"),
// $0.05 worth of phone storage in 2020
maxSize = 50L * 1024L * 1024L // 50 MiB
))
.build()

EventListener事件

Cache事件通过 EventListener API 暴露,典型场景如下:

Cache Hit(缓存命中)

在理想的情况下,缓存在不需要请求网络的情况下响应请求。这会跳过通过所需的事件,比如DNS、网络连接以及响应体的下载。

  • CallStart
  • CallStart
  • CallEnd

Cache Miss

Under a cache miss the normal request events are seen but an additional event shows the presence of the cache. Cache Miss will be typical if the item has not been read from the network, is uncacheable, or is past it’s lifetime based on Response cache headers.

  • CallStart
  • CacheMiss
  • ProxySelectStart
  • … Standard Events …
  • CallEnd

Conditional Cache Hit

When cache flags require checking the cache results are still valid an early cacheConditionalHit event is received followed by a cache hit or miss. Critically in the cache hit scenario the server won’t send the response body.

The response will have non-null cacheResponse and networkResponse. The cacheResponse will be used as the top level response only if the response code is HTTP/1.1 304 Not Modified.

  • CallStart
  • CacheConditionalHit
  • ConnectionAcquired
  • … Standard Events…
  • ResponseBodyEnd (0 bytes)
  • CacheHit
  • ConnectionReleased
  • CallEnd

Cache directory

The cache directory must be exclusively owned by a single instance.

Deleting the cache when it is no longer needed can be done. However this may delete the purpose of the cache which is designed to persist between app restarts.

cache.delete()

Pruning the Cache

Pruning the entire Cache to clear space temporarily can be done using evictAll.

cache.evictAll()

Removing individual items can be done using the urls iterator. This would be typical after a user initiates a force refresh by a pull to refresh type action.

val urlIterator = cache.urls()
while (urlIterator.hasNext()) {
if (urlIterator.next().startsWith("https://www.google.com/")) {
urlIterator.remove()
}
}

Troubleshooting

  1. Valid cacheable responses are not being cached

Make sure you are reading responses fully as unless they are read fully, cancelled or stalled Responses will not be cached.

Overriding normal cache behaviour¶

See Cache documentation. https://square.github.io/okhttp/4.x/okhttp/okhttp3/-cache/

原文 - Caching