如何使用Glide在不加载Bitmap的情况下完成缓存?
嘿,我完全懂你说的这种冗余感——刚把本地图片传到服务器,转头又要从服务器拉回来展示,确实有点折腾。其实Glide本身就支持直接把本地Bitmap缓存起来,不用走一遍网络加载流程,核心思路是让本地Bitmap的缓存Key和后续加载服务器图片时的Key完全一致,这样Glide就能直接从缓存取,不用发起网络请求。下面给你两个实用的方案:
方案一:利用Glide预加载绑定服务器URL缓存Key
这个方法最省心,直接用Glide的预加载功能,把本地Bitmap和服务器返回的图片URL绑定缓存:
// 上传完成后拿到的服务器图片URL val serverImageUrl = "https://your-server-domain.com/uploaded-image.jpg" // 你要缓存的本地Bitmap val localBitmap: Bitmap = ... // 从本地相册/文件获取的Bitmap Glide.with(applicationContext) .load(localBitmap) // 同时缓存到内存和磁盘 .diskCacheStrategy(DiskCacheStrategy.ALL) .apply( RequestOptions() // 用服务器URL作为缓存签名,确保缓存Key和后续加载该URL时一致 .signature(ObjectKey(serverImageUrl)) ) .preload() // 只缓存不显示到View
之后你再用Glide加载serverImageUrl到GridView时,就会直接命中缓存,不用请求服务器:
Glide.with(context) .load(serverImageUrl) .signature(ObjectKey(serverImageUrl)) // 必须和预加载时的签名一致 .into(gridViewItemImageView)
方案二:手动操作Glide缓存(更灵活可控)
如果需要更精细的控制缓存逻辑,可以直接操作Glide的内存和磁盘缓存:
val serverImageUrl = "https://your-server-domain.com/uploaded-image.jpg" val localBitmap: Bitmap = ... // 生成和后续加载服务器URL时完全一致的缓存Key val cacheKey = Glide.with(applicationContext) .load(serverImageUrl) .signature(ObjectKey(serverImageUrl)) .generateKey() // 1. 存入内存缓存(主线程可执行) val bitmapResource = BitmapResource.obtain(localBitmap, Glide.get(applicationContext).bitmapPool) Glide.get(applicationContext).memoryCache.put(cacheKey, bitmapResource) // 2. 存入磁盘缓存(必须在子线程执行,避免ANR) CoroutineScope(Dispatchers.IO).launch { val isSaved = Glide.get(applicationContext).diskCache.put(cacheKey) { cacheFile -> return@put try { FileOutputStream(cacheFile).use { outputStream -> localBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream) } true } catch (e: IOException) { e.printStackTrace() false } } // 可选:判断缓存是否成功 if (isSaved) { Log.d("GlideCache", "本地Bitmap缓存到磁盘成功") } }
关键注意事项
- 缓存Key必须完全一致:如果后续加载服务器URL时用了
centerCrop()、circleCrop()这类变换,或者添加了其他签名参数,预加载/手动缓存时必须完全同步这些配置,否则Glide会生成不同的缓存Key,导致无法命中。 - 磁盘缓存要异步:磁盘IO操作不能在主线程执行,方案二中用了Coroutine切换到IO线程,你也可以用AsyncTask或者其他异步方式。
- Bitmap生命周期管理:存入Glide缓存后,Glide会自动管理Bitmap的回收,你不用手动调用
recycle(),但要注意不要持有Bitmap的强引用导致内存泄漏。 - 版本适配:以上代码基于Glide 4.x,如果是Glide 3.x,API会有差异(比如
RequestOptions对应GlideOptions,缓存Key生成方式不同),需要调整。
内容的提问来源于stack exchange,提问作者Gleb Ger
相关产品推荐
相关产品推荐

