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

使用Glide加载固定URL图片时如何在新图加载时显示缓存并更新缓存?

问题原因

Glide的缓存键由资源URL、签名参数、请求参数(尺寸、变换等)共同计算生成。你在updateImage方法中使用ObjectKey(System.currentTimeMillis())作为动态签名,相当于每次拉新请求的缓存键都不同,新下载的图片会存储到对应当前时间戳的独立缓存键下,和loadImage方法中使用默认签名的请求的缓存键完全不匹配,因此后续读缓存永远只能拿到第一次加载的旧图片。

修复方案

方案1:通过HTTP头强制刷新(推荐)

利用HTTP标准缓存控制头强制拉取最新资源,不需要修改签名参数,Glide会自动将新资源覆盖原URL对应的缓存,无需额外处理。
修改后的代码如下:

import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.load.model.Headers
import com.bumptech.glide.load.model.LazyHeaders

// loadImage 方法不需要修改
fun loadImage(context: Context, imageView: ImageView, url: String?) {
 Glide.with(context)
  .asBitmap()
  .load(url)
  .onlyRetrieveFromCache(true)
  .into(object : CustomTarget<Bitmap>() {
   override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
    updateImage(context, imageView, url, resource)
   }

   override fun onLoadFailed(errorDrawable: Drawable?) {
    updateImage(context, imageView, url, null)
   }

   override fun onLoadCleared(placeholder: Drawable?) {}
  })
}

private fun updateImage(context: Context, imageView: ImageView, url: String?, placeholder: Bitmap?) {
    url ?: return
    // 构造带Cache-Control头的请求地址,强制拉取最新资源
    val glideUrl = GlideUrl(url, object : LazyHeaders.Builder() {
        override fun build(): Headers {
            return Headers.Builder()
                .add("Cache-Control", "no-cache")
                .build()
        }
    }.build())

    Glide.with(context)
        .setDefaultRequestOptions(RequestOptions().timeout(30000))
        .load(glideUrl)
        .placeholder(BitmapDrawable(context.resources, placeholder))
        .dontAnimate()
        .into(imageView)
}

方案2:手动同步缓存(适合服务器不支持缓存头的场景)

如果服务器无法适配缓存头控制,可以保留原有拉新逻辑,在新图片下载完成后手动写入原URL对应的缓存:

private fun updateImage(context: Context, imageView: ImageView, url: String?, placeholder: Bitmap?) {
    url ?: return
    Glide.with(context)
        .asBitmap()
        .setDefaultRequestOptions(RequestOptions().timeout(30000))
        .load(url)
        .signature(ObjectKey(System.currentTimeMillis()))
        .placeholder(BitmapDrawable(context.resources, placeholder))
        .dontAnimate()
        .into(object : CustomTarget<Bitmap>() {
            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                // 先更新UI展示新图
                imageView.setImageBitmap(resource)
                // 手动将新图写入原URL对应的缓存
                Glide.with(context)
                    .downloadOnly()
                    .load(url)
                    .into(object : CustomTarget<File>() {
                        override fun onResourceReady(cacheFile: File, transition: Transition<in File>?) {
                            // 把新下载的bitmap写入缓存文件
                            runCatching {
                                val outputStream = FileOutputStream(cacheFile)
                                resource.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
                                outputStream.flush()
                                outputStream.close()
                            }
                        }
                        override fun onLoadCleared(placeholder: Drawable?) {}
                    })
            }
            override fun onLoadCleared(placeholder: Drawable?) {}
        })
}
逻辑验证

修改后可以满足你的所有需求:

  • 启动时优先读取缓存中的旧图片展示
  • 后台自动拉取服务器最新图片
  • 新图片拉取完成后自动覆盖原有缓存
  • 界面同步更新为最新图片

内容的提问来源于stack exchange,提问作者BArtWell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:54:05