以下是通过实例讲解 Glide 资源回收与复用的常见应用场景,涵盖内存优化、性能调优和特殊场景处理,帮助开发者避免内存泄漏和提升应用流畅度。
Glide 资源管理核心机制
- BitmapPool:复用已释放的 Bitmap 内存,减少 GC 频率。
- 活动缓存 (Active Resources):弱引用缓存正在使用的资源。
- 内存缓存 (Memory Cache):LRU 缓存最近使用的资源。
- 生命周期绑定:自动释放与界面关联的资源。
场景 1:列表滑动时的资源回收(防止内存抖动)
需求:在 RecyclerView 或 ListView 中,快速滑动时及时回收不可见项的图片资源。
实现:在 onViewRecycled 中主动释放资源。
// RecyclerView.Adapter 中的 ViewHolder
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(url: String) {
Glide.with(itemView)
.load(url)
.into(itemView.imageView)
}
fun clear() {
Glide.with(itemView).clear(itemView.imageView) // 手动释放资源
}
}
// 在 Adapter 中回收资源
override fun onViewRecycled(holder: MyViewHolder) {
holder.clear()
super.onViewRecycled(holder)
}
场景 2:手动释放页面所有请求
需求:在 Activity/Fragment 销毁时,释放所有未完成的请求和资源。
实现:在 onDestroy 中调用 Glide.with(context).pauseRequests() 或 clear。
// Activity 或 Fragment 中
override fun onDestroy() {
// 释放当前页面所有请求
Glide.with(this).pauseRequests()
// 或者直接清除所有关联请求
Glide.with(this).clear(imageView)
super.onDestroy()
}
场景 3:复用 BitmapPool 优化大图加载
需求:加载大图时复用 Bitmap 内存,避免频繁分配内存导致卡顿。
实现:在自定义 Transformation 中通过 BitmapPool 获取 Bitmap。
class CustomTransformation : BitmapTransformation() {
override fun transform(
pool: BitmapPool,
source: Bitmap,
outWidth: Int,
outHeight: Int
): Bitmap {
// 从 BitmapPool 中复用内存
val recycledBitmap = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888)
// 在复用的 Bitmap 上绘制内容(示例:灰度处理)
val canvas = Canvas(recycledBitmap)
val paint = Paint()
val matrix = ColorMatrix().apply { setSaturation(0f) }
paint.colorFilter = ColorMatrixColorFilter(matrix)
canvas.drawBitmap(source, 0f, 0f, paint)
return recycledBitmap
}
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
messageDigest.update("custom_transformation".toByteArray())
}
}
场景 4:主动清理内存缓存
需求:在内存不足或特定场景(如切换用户)时主动释放缓存。
实现:调用 clearMemory() 或响应系统内存警告。
// 手动清理内存缓存(需在主线程调用)
Glide.get(context).clearMemory()
// 在 Application 中监听内存压力
class MyApp : Application() {
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
Glide.get(this).clearMemory()
}
}
}
场景 5:自定义 BitmapPool 配置
需求:优化 BitmapPool 策略以适应特殊场景(如大量 ARGB_8888 格式图片)。
实现:通过 GlideModule 配置自定义 BitmapPool。
@GlideModule
class CustomGlideModule : AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) {
// 创建支持大尺寸 ARGB_8888 的 BitmapPool
val bitmapPool = LruBitmapPool(
maxSize = 1024 * 1024 * 100, // 100MB
allowedConfigs = mutableListOf(Bitmap.Config.ARGB_8888),
trackMutableBitmaps = true
)
builder.setBitmapPool(bitmapPool)
}
}
场景 6:非 ImageView 目标的资源回收
需求:当加载图片到自定义 Target 或 View 时,需手动管理资源生命周期。
实现:实现 Target 接口并重写 onDestroy。
// 自定义 Target
val target = object : CustomTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
customView.setBitmap(resource)
}
override fun onLoadCleared(placeholder: Drawable?) {
// 主动释放资源
customView.setBitmap(null)
}
}
// 加载并绑定生命周期
Glide.with(context)
.asBitmap()
.load(url)
.into(target)
// 在适当时候释放
fun onDestroy() {
Glide.with(context).clear(target)
}
场景 7:复用解码后的资源(跨页面共享)
需求:在多页面中共享同一图片资源(如用户头像),避免重复解码。
实现:通过 MemoryCache 手动存取资源。
// 存储资源
Glide.with(context)
.load(url)
.into(object : CustomTarget<Drawable>() {
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
val key = Glide.get(context).memoryCache.generateKey(url, 100, 100)
Glide.get(context).memoryCache.put(key, resource)
}
})
// 读取复用资源
val key = Glide.get(context).memoryCache.generateKey(url, 100, 100)
val cachedResource = Glide.get(context).memoryCache.get(key)
if (cachedResource != null) {
imageView.setImageDrawable(cachedResource)
} else {
Glide.with(context).load(url).into(imageView)
}
最佳实践与注意事项
-
生命周期绑定:
- 使用
Glide.with(Activity/Fragment)而非ApplicationContext,避免生命周期错乱。 - 在
View复用时(如RecyclerView),必须调用Glide.clear()。
- 使用
-
BitmapPool 优化:
- 优先使用
Bitmap.Config.RGB_565(内存占用减少 50%)。 - 避免在
Transformation中创建新 Bitmap,尽量复用BitmapPool。
- 优先使用
-
调试工具:
- 开启详细日志:
adb shell setprop log.tag.Glide VERBOSE - 检查内存缓存状态:
Glide.get(context).memoryCache.size
- 开启详细日志:
总结:场景与解决方案
| 场景 | 技术方案 |
|---|---|
| 列表滑动优化 | onViewRecycled 中调用 clear() |
| 页面销毁释放资源 | onDestroy 中调用 pauseRequests() 或 clear() |
| 大图内存复用 | 自定义 Transformation 使用 BitmapPool |
| 主动清理缓存 | clearMemory() + 响应 onTrimMemory |
| 非 ImageView 资源管理 | 自定义 Target + 实现 onLoadCleared |
| 跨页面资源共享 | 手动操作 MemoryCache |
通过合理管理资源回收与复用,可以显著降低内存占用、减少卡顿并提升用户体验。在内存敏感场景(如低端设备、图片密集型应用)中,建议结合 Memory Profiler 工具持续监控优化。
当前文章价值6.32元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

评论已关闭!