android Glide 使用详解

Android Glide 使用详解

Glide 是 Android 平台上最受欢迎的图片加载库之一,由 Bump Technologies 开发,后被 Google 推荐为官方图片加载方案。


一、什么是 Glide

Glide 是一个快速、高效、开源的 Android 图片加载库,专注于:

  • 平滑滚动:自动处理图片加载与列表滚动的性能平衡

  • 内存优化:智能的内存缓存和磁盘缓存策略

  • GIF 支持:原生支持加载和显示 GIF 动画

  • 视频缩略图:支持从视频文件中提取缩略图


二、基本集成

1. 添加依赖

groovy

复制代码
// build.gradle (Module: app)
dependencies {
    implementation 'com.github.bumptech.glide:glide:4.16.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
}

2. 基础用法

kotlin

复制代码
// 加载网络图片
Glide.with(context)
    .load("https://example.com/image.jpg")
    .into(imageView)

// 加载本地资源
Glide.with(context)
    .load(R.drawable.image)
    .into(imageView)

// 加载本地文件
Glide.with(context)
    .load(File("/path/to/image.jpg"))
    .into(imageView)

// 加载 URI
Glide.with(context)
    .load(uri)
    .into(imageView)

三、核心 API 详解

1. with() --- 生命周期绑定

kotlin

复制代码
// 绑定 Activity 生命周期(推荐)
Glide.with(activity)
// 绑定 Fragment 生命周期
Glide.with(fragment)
// 绑定 View 生命周期
Glide.with(view)
// 绑定 Application 生命周期(全局,不推荐常规使用)
Glide.with(context.applicationContext)

关键特性:Glide 会自动根据绑定的生命周期暂停/恢复/销毁请求,避免内存泄漏。

2. load() --- 数据来源

支持多种数据类型:

  • String --- URL 或文件路径

  • Uri --- 内容提供者 URI

  • File --- 本地文件

  • Integer --- 资源 ID

  • Drawable --- 已有 Drawable

  • Bitmap --- 已有 Bitmap

  • byte[] --- 字节数组

  • URL --- Java URL 对象

3. into() --- 目标视图

kotlin

复制代码
// 加载到 ImageView
.into(imageView)

// 加载到自定义 Target(获取 Bitmap)
.into(object : CustomTarget<Bitmap>() {
    override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
        // 处理 Bitmap
    }
    override fun onLoadCleared(placeholder: Drawable?) {}
})

四、常用配置选项

占位图与错误图

kotlin

复制代码
Glide.with(context)
    .load(url)
    .placeholder(R.drawable.loading)      // 加载中占位图
    .error(R.drawable.error)              // 加载失败图
    .fallback(R.drawable.empty)           // 传入 null 时显示
    .into(imageView)

图片变换

kotlin

复制代码
Glide.with(context)
    .load(url)
    .centerCrop()           // 居中裁剪,填满视图
    .fitCenter()            // 居中适配,完整显示
    .circleCrop()           // 圆形裁剪
    .into(imageView)

尺寸调整

kotlin

复制代码
Glide.with(context)
    .load(url)
    .override(300, 200)     // 指定加载尺寸(像素)
    .into(imageView)

缓存策略

kotlin

复制代码
Glide.with(context)
    .load(url)
    .skipMemoryCache(true)              // 跳过内存缓存
    .diskCacheStrategy(DiskCacheStrategy.NONE)  // 跳过磁盘缓存
    .into(imageView)

磁盘缓存策略:

策略 说明
ALL 缓存原始图片和转换后的图片(默认)
NONE 不缓存
DATA 仅缓存原始图片
RESOURCE 仅缓存转换后的图片
AUTOMATIC 智能选择(推荐)

三级缓存

1. 活动缓存(Active Resources)

  • 作用 :缓存当前正在被使用的图片资源(即有强引用指向它的 ImageView 还在屏幕上显示)

  • 特点 :使用 HashMap 管理,key 是 EngineKey,value 是 Resource 的弱引用或引用计数

  • 生命周期:当 ImageView 不再引用该资源(如页面销毁、图片切换)时,从活动缓存移出,进入内存缓存

2. 内存缓存(Memory Cache)

  • 作用 :缓存最近使用过但当前未被显示的图片

  • 实现 :LruResourceCache,继承自 LruCache,默认大小为设备内存的某个比例(可通过 MemorySizeCalculator 计算)

  • 淘汰策略:LRU(Least Recently Used),当内存不足时淘汰最久未使用的

  • 注意:从内存缓存取出的图片需要重新进入活动缓存才能使用

3. 磁盘缓存(Disk Cache)

  • 作用:持久化缓存,避免重复网络请求

  • 实现 :默认使用 DiskLruCache

  • 两种模式:

    • AUTOMATIC:根据图片来源自动决定

    • ALL:缓存原始数据和转换后的数据

    • DATA:只缓存原始数据

    • RESOURCE:只缓存转换后的数据

    • NONE:不缓存


加载流程(简化版)

plain

复制代码
请求图片
   ↓
1. 检查 Active Resources(活动缓存)→ 命中则直接返回
   ↓ 未命中
2. 检查 Memory Cache(内存缓存)→ 命中则移入 Active Resources 并返回
   ↓ 未命中
3. 检查 Disk Cache(磁盘缓存)→ 命中则解码后移入 Memory/Active 并返回
   ↓ 未命中
4. 从网络/本地加载 → 解码 → 写入 Disk → 写入 Memory → 移入 Active → 返回

常见误区

错误说法 正确说法
"内存缓存 = LruCache 一层" 内存层面其实是 两层:Active Resources + LruCache
"三级缓存是内存、磁盘、网络" 网络不是缓存,是数据源。三级是 Active、Memory、Disk

五、高级用法

1. 自定义 Transformation

kotlin

复制代码
class BlurTransformation(private val radius: Int) : BitmapTransformation() {
    override fun transform(
        pool: BitmapPool,
        toTransform: Bitmap,
        outWidth: Int,
        outHeight: Int
    ): Bitmap {
        // 实现高斯模糊逻辑
        return blurBitmap(toTransform, radius)
    }

    override fun updateDiskCacheKey(messageDigest: MessageDigest) {
        messageDigest.update("blur_$radius".toByteArray())
    }
}

// 使用
Glide.with(context)
    .load(url)
    .transform(BlurTransformation(25))
    .into(imageView)

2. 预加载图片

kotlin

复制代码
// 预加载到内存和磁盘缓存(不显示)
Glide.with(context)
    .load(url)
    .preload(300, 200)

// 预加载到指定尺寸
Glide.with(context)
    .load(url)
    .preload()

3. 下载图片(不显示)

kotlin

复制代码
Glide.with(context)
    .asBitmap()
    .load(url)
    .into(object : CustomTarget<Bitmap>(300, 200) {
        override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
            // 获取到 Bitmap,自行处理
        }
        override fun onLoadCleared(placeholder: Drawable?) {}
    })

4. 加载 GIF

kotlin

复制代码
// 加载 GIF(自动播放)
Glide.with(context)
    .asGif()
    .load(url)
    .into(imageView)

// 加载为静态 Bitmap(取第一帧)
Glide.with(context)
    .asBitmap()
    .load(gifUrl)
    .into(imageView)

5. 设置请求优先级

kotlin

复制代码
Glide.with(context)
    .load(url)
    .priority(Priority.HIGH)  // IMMEDIATE, HIGH, NORMAL, LOW
    .into(imageView)

六、Glide 模块(自定义全局配置)

创建 AppGlideModule

kotlin

复制代码
@GlideModule
class MyAppGlideModule : AppGlideModule() {
    override fun applyOptions(context: Context, builder: GlideBuilder) {
        // 设置默认占位图
        builder.setDefaultRequestOptions(
            RequestOptions()
                .placeholder(R.drawable.loading)
                .error(R.drawable.error)
        )
        
        // 设置内存缓存大小
        val memoryCacheSizeBytes = 1024 * 1024 * 20 // 20MB
        builder.setMemoryCache(LruResourceCache(memoryCacheSizeBytes.toLong()))
        
        // 设置磁盘缓存
        val diskCacheSizeBytes = 1024 * 1024 * 100 // 100MB
        builder.setDiskCache(InternalCacheDiskCacheFactory(context, diskCacheSizeBytes.toLong()))
        
        // 设置日志级别
        builder.setLogLevel(Log.DEBUG)
    }

    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        // 注册自定义组件(如自定义 ModelLoader、Encoder 等)
    }

    // 禁用 Manifest 解析(提升初始化速度)
    override fun isManifestParsingEnabled(): Boolean = false
}

七、与 Picasso / Coil 对比

特性 Glide Picasso Coil
体积 较大(~500KB) 中等(~100KB) 较小(依赖 Kotlin Coroutines)
GIF 支持 ✅ 原生支持 ❌ 不支持 ✅ 支持
视频缩略图 ✅ 支持 ❌ 不支持 ✅ 支持
内存占用 较低(复用 Bitmap) 较高 较低
图片质量 默认 RGB_565 默认 ARGB_8888 默认 ARGB_8888
Kotlin 友好 一般 一般 ✅ 专为 Kotlin 设计
生命周期管理 ✅ 完善 ✅ 完善 ✅ 完善
SVG 支持 需扩展 需扩展 ✅ 内置支持

八、最佳实践

✅ 推荐做法

  1. 始终绑定生命周期 :使用 Glide.with(activity) 而非 Glide.with(context)

  2. 指定加载尺寸 :使用 .override() 避免加载过大图片

  3. 复用 RequestOptions:

    kotlin

    复制代码
    val options = RequestOptions()
        .placeholder(R.drawable.loading)
        .error(R.drawable.error)
        .centerCrop()
    
    Glide.with(context).load(url1).apply(options).into(iv1)
    Glide.with(context).load(url2).apply(options).into(iv2)
  4. 列表中使用:RecyclerView 中 Glide 会自动处理复用和取消请求

❌ 避免做法

  1. 不要在 into() 中传入新创建的 ImageView

  2. 不要在主线程进行大量图片处理

  3. 不要忽略占位图设置(会导致加载闪烁)


九、常见问题

问题 解决方案
图片加载后变形 确保 ImageView 的 scaleType 与 Glide 的变换一致
图片加载模糊 检查是否被压缩,使用 .override(Target.SIZE_ORIGINAL)
内存溢出 使用 .override() 限制尺寸,或降低图片质量
缓存不生效 确保 URL 不变,或调整 diskCacheStrategy
加载 HTTPS 图片失败 配置 OkHttp 信任所有证书(开发环境)

相关推荐
火柴就是我8 小时前
Flutter 项目本地 Maven 引入 AAR 找不到?一次 Gradle 路径问题排查
android
火柴就是我8 小时前
Android 打包报错 25.0.3
android·前端
码上有光8 小时前
Linux进程通信——共享内存、消息队列和信号量
android·linux·运维·共享内存·通信
Android打工仔12 小时前
Kotlin 协程源码解析:DispatchedContinuation 里的 Dispatcher 从哪里来?
android·kotlin
打工仔折腾 AI13 小时前
从BPE到SentencePiece:Transformer分词原理与Python实战对比
android·人工智能·python·深度学习·langchain·transformer·ai agent 实战
Dovis(誓平步青云)13 小时前
几个方案来回选不定?做一个随时切换的候选推荐页
android·java·服务器·开发语言·javascript·数据库·智能化
恋猫de小郭17 小时前
KMP 又改了编译流程, Separate Compilation 禁止了 `commonMain` 的依赖穿透
android·前端·flutter
执明wa17 小时前
Android RecyclerView 实战:点击频道栏切换对应内容
android·开发语言·windows·microsoft·android studio
新鲜势力呀18 小时前
PHP 定时数据同步实战:从第三方接口超时到异步同步 + 增量更新架构优化全过程
android
星间都市山脉19 小时前
RecoveryUI 圆角屏安全边距配置及代码调用链
android·java·linux·windows·ubuntu