You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断图片是否已在Coil管理的内存缓存中?

解决Coil缓存检查实现立即跳转的问题

要实现点击已缓存图片时立即跳转,你可以通过Coil提供的缓存API分别检查内存缓存和磁盘缓存,具体实现如下:

1. 检查内存缓存

直接通过ImageLoader的memoryCache获取缓存项,传入与图片加载时一致的缓存key(这里使用你的imageUrl):

val memoryCacheKey = MemoryCache.Key(imageUrl)
val isInMemoryCache = imageLoader.memoryCache.get(memoryCacheKey) != null

2. 检查磁盘缓存

磁盘缓存的检查是挂起操作,需要在IO线程执行,通过ImageLoader的diskCache打开快照判断缓存是否存在:

val diskCacheKey = DiskCache.Key(imageUrl)
val isInDiskCache = withContext(Dispatchers.IO) {
    imageLoader.diskCache?.openSnapshot(diskCacheKey)?.use { true } ?: false
}

修改后的ViewModel核心代码

将缓存检查逻辑整合到getPhotoById方法中,调整后的完整代码如下:

fun getPhotoById(id: String, imageLoader: ImageLoader, context: Context) {
    viewModelScope.launch {
        val infoBook = safeApiCall {
            bookRepository.getBookById(id).volumeInfo
        }
        infoBook?.let {
            val imageUrl = it.imageLinks?.medium.toString().replace("http:", "https:")
            updateBookUiState(
                thumbnail = imageUrl,
                title = it.title,
                authors = it.authors?.joinToString(", ") ?: "Unknown",
                description = HtmlCompat.fromHtml(it.description.orEmpty(), HtmlCompat.FROM_HTML_MODE_LEGACY).toString()
            )

            // 检查内存缓存
            val memoryCacheKey = MemoryCache.Key(imageUrl)
            val isInMemoryCache = imageLoader.memoryCache.get(memoryCacheKey) != null
            
            // 检查磁盘缓存
            val diskCacheKey = DiskCache.Key(imageUrl)
            val isInDiskCache = withContext(Dispatchers.IO) {
                imageLoader.diskCache?.openSnapshot(diskCacheKey)?.use { true } ?: false
            }

            val isCached = isInMemoryCache || isInDiskCache
            if (isCached) {
                shouldNavigate = true
            } else {
                // 原有图片加载逻辑
                val request = ImageRequest.Builder(context)
                    .data(imageUrl)
                    .diskCachePolicy(CachePolicy.ENABLED)
                    .memoryCachePolicy(CachePolicy.ENABLED)
                    .networkCachePolicy(CachePolicy.ENABLED)
                    .diskCacheKey(imageUrl)
                    .memoryCacheKey(imageUrl)
                    .decoderFactory { _, _, _ ->
                        Decoder { DecodeResult(ColorDrawable(Color.BLACK), false) }
                    }
                    .listener(
                        onStart = { _ ->
                            fetchPhotoBook = FetchPhotoBook.Loading
                            Log.d("Request Start", "Start")
                        },
                        onSuccess = { _, _ ->
                            shouldNavigate = true
                        }
                    )
                    .build()
                imageLoader.enqueue(request)
            }
        } ?: run {
            Log.d("BOOK_INFO", "No data found")
        }
    }
}

关键注意点

  • 缓存key必须与图片加载时设置的memoryCacheKey、diskCacheKey完全一致,否则检查会失败;
  • 磁盘缓存检查必须在IO线程执行,避免阻塞主线程;
  • 只要内存或磁盘任一缓存存在,就立即触发跳转,否则等待图片加载完成后再执行跳转。

内容的提问来源于stack exchange,提问作者Trần Thanh Vinh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:44:50