Jetpack Compose中Coil 2.1.0图片缓存离线无法加载问题
问题修复方案
你的现有配置存在3处核心遗漏,直接导致断网状态下无法命中缓存:
- 未关闭HTTP缓存头校验:Coil 2.x版本默认开启
respectCacheHeaders = true配置,会严格遵守图片服务端返回的HTTP缓存规则,如果接口返回的图片响应头携带no-cache、no-store、max-age=0这类禁用缓存的标记,即使你手动开启了磁盘缓存,图片也不会被写入磁盘,离线状态自然无法读取。 - 磁盘缓存容量设置过小:当前配置的磁盘缓存上限仅为5MB,单张普通分辨率的网络图片大小就可能达到1-2MB,LRU缓存淘汰策略会很快清理掉较早存入的图片,你认为已经缓存的资源实际早就被删除。
- 缓存策略逻辑适配缺失:
CachePolicy.ENABLED的默认逻辑是「优先读取缓存,缓存不存在时发起网络请求」,但断网状态下网络请求会直接抛出无网络异常,Coil不会在请求失败后自动回退读取磁盘缓存;另外你手动为请求指定了和原始URL一致的磁盘缓存Key,但你添加了CircleCropTransformation裁剪转换,转换后的图片默认仅写入内存缓存,不会存入磁盘,应用进程被杀后内存缓存释放,离线就无法读取到裁剪后的图片。
正确配置代码
首先修改全局ImageLoader初始化逻辑:
class App : Application(), ImageLoaderFactory { override fun newImageLoader(): ImageLoader { return ImageLoader.Builder(this) .memoryCache { MemoryCache.Builder(this) .maxSizePercent(0.25) .build() } .diskCache { DiskCache.Builder() .directory(cacheDir.resolve("image_cache")) // 磁盘缓存建议设置为100MB-250MB,可根据业务需求调整,不建议低于50MB .maxSizeBytes(100 * 1024 * 1024) .build() } // 关键配置:忽略服务端返回的缓存头限制,强制将加载成功的网络图片写入磁盘缓存 .respectCacheHeaders(false) .build() } }
再修改Compose侧的图片加载逻辑:
val context = LocalContext.current val placeholderImage = R.drawable.ic_placeholder // 用remember缓存请求实例,避免每次重组重复创建对象 val imageRequest = remember(imageUrl) { ImageRequest.Builder(context) .data(imageUrl) // 无需手动指定内存/磁盘缓存Key,Coil默认会将图片URL、转换规则、尺寸等参数联合生成唯一Key,手动指定反而可能引发Key冲突 .placeholder(placeholderImage) .error(placeholderImage) .fallback(placeholderImage) .memoryCachePolicy(CachePolicy.ENABLED) // 根据网络状态切换磁盘缓存策略:联网时可读可写,断网时只读缓存、不发起网络请求 .diskCachePolicy(if (isNetworkAvailable(context)) CachePolicy.ENABLED else CachePolicy.CACHE_ONLY) .transformations(CircleCropTransformation()) .build() } AsyncImage( model = imageRequest, modifier = Modifier.size(64.dp), contentDescription = null )
注:isNetworkAvailable(context)为自行实现的网络状态检测方法,用于判断当前设备是否连通网络。
内容的提问来源于stack exchange,提问作者lokesh
相关产品推荐
相关产品推荐

