如何配置Coil优先使用本地缓存而非网络拉取图片?
Coil 2.2.2 优先使用本地缓存而非网络请求的实现方案
你的核心问题在于当前设置的networkCachePolicy(CachePolicy.ENABLED)遵循HTTP缓存协议,默认情况下即使存在本地缓存,Coil仍会发起网络请求校验缓存是否新鲜(比如发送If-None-Match或If-Modified-Since头),因此有网络时仍会触发网络请求。
要实现优先使用本地缓存,仅缓存不存在时才请求网络,可以通过以下几种方式实现:
方案一:针对单个请求添加Cache-Control头
通过设置Cache-Control头,强制OkHttp仅从缓存读取资源,不发起网络请求:
ImageRequest.Builder(context) .data(imageUrl) .memoryCachePolicy(CachePolicy.ENABLED) .diskCachePolicy(CachePolicy.ENABLED) // 强制仅使用缓存,允许缓存过期1年(可按需调整时长) .addHeader("Cache-Control", "only-if-cached, max-stale=31536000") .diskCacheKey(imageUrl) .memoryCacheKey(imageUrl) .size(Size.ORIGINAL) .build()
only-if-cached:告诉OkHttp仅从缓存获取资源,不发起新的网络请求max-stale=31536000:允许使用已过期的缓存,这里设置为1年,你可以根据业务需求调整过期时长
方案二:修改NetworkCachePolicy为READ_ONLY
Coil的NetworkCachePolicy.READ_ONLY配置表示仅读取HTTP缓存,不发起新的网络请求,结合磁盘和内存缓存启用即可实现需求:
ImageRequest.Builder(context) .data(imageUrl) .memoryCachePolicy(CachePolicy.ENABLED) .diskCachePolicy(CachePolicy.ENABLED) .networkCachePolicy(CachePolicy.READ_ONLY) .diskCacheKey(imageUrl) .memoryCacheKey(imageUrl) .size(Size.ORIGINAL) .build()
注意:该方案依赖HTTP缓存的有效性,如果缓存已过期,Coil会无法读取缓存,此时可以结合方案一的Cache-Control头来允许使用过期缓存。
方案三:全局配置(所有请求生效)
如果希望所有图片请求都优先使用缓存,可以自定义OkHttpClient并设置默认的缓存策略,再替换Coil默认的ImageLoader:
1. 自定义OkHttpClient
val okHttpClient = OkHttpClient.Builder() .cache(Cache(context.cacheDir, 100 * 1024 * 1024)) // 设置100MB磁盘缓存 .addInterceptor { chain -> val modifiedRequest = chain.request().newBuilder() .header("Cache-Control", "only-if-cached, max-stale=31536000") .build() chain.proceed(modifiedRequest) } .build()
2. 初始化自定义ImageLoader
val customImageLoader = ImageLoader.Builder(context) .okHttpClient(okHttpClient) .build()
3. 在Compose中使用自定义ImageLoader
AsyncImage( model = ImageRequest.Builder(context) .data(imageUrl) .diskCacheKey(imageUrl) .memoryCacheKey(imageUrl) .size(Size.ORIGINAL) .build(), imageLoader = customImageLoader, contentDescription = null // 按需设置内容描述 )
内容的提问来源于stack exchange,提问作者Anudeep Ananth
相关产品推荐
相关产品推荐

