Glide 是一个功能强大的 Android 图片加载库,它支持加载多种类型的图片格式。以下是 Glide 可以处理的一些常见图片类型:

  1. JPEG: 支持加载 JPEG 格式的图片。
  2. PNG: 支持加载 PNG 格式的图片,包括具有透明背景的图片。
  3. GIF: 支持加载 GIF 动画,并能够播放动画或将其作为静态帧显示。
  4. WebP: 支持加载 Google 的 WebP 格式图片,包括无损和有损压缩的变体。
  5. Bitmap: 可以直接加载 Android 的 Bitmap 对象。
  6. Vector Drawable: 支持加载 Android 的矢量图形资源(VectorDrawable),如 SVG 文件在 Android 中的表示。
  7. Base64: 支持从 Base64 编码的字符串加载图片。
  8. 文件路径: 可以加载文件系统中的图片文件。
  9. 资源 ID: 可以直接加载项目资源文件夹中的图片资源(例如 R.drawable.image)。
  10. URL: 支持从网络 URL 加载图片。

1、添加依赖:

在项目的 build.gradle 文件(Module: app)的 dependencies 部分添加 Glide 的依赖项:

dependencies {
    ...
    implementation("com.github.bumptech.glide:glide:4.12.0")
    annotationProcessor ("com.github.bumptech.glide:compiler:4.12.0")
    ...
}


2、引入权限

  1. android.permission.INTERNET:允许应用程序访问网络。
  2. android.permission.ACCESS_NETWORK_STATE:允许应用程序访问信息关于所有网络状态,例如WiFi是否连接。
  3. android.permission.READ_EXTERNAL_STORAGE:允许应用程序读取存储在外部存储上的文件,例如SD卡。
  4. android.permission.WRITE_EXTERNAL_STORAGE:允许应用程序写入存储在外部存储上的文件,例如SD卡。
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


3、加载图片

(1)加载静态图片:

使用 Glide 加载图片的基本方法是链式调用。Glide 理论上可以加载任何类型的数据,只要能够被转换成 Bitmap 或其他视图可以显示的格式。

使用方式:首先调用 Glide.with(context),然后指定要加载的图片资源,最后调用 into(imageView) 将图片设置到 ImageView。

class MainActivity : ComponentActivity() {

    private lateinit var binding:ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        super.onCreate(savedInstanceState)
        binding.inputPic.setOnClickListener{
            //设置图片
            Glide.with(this)
                //设置图片资源的路径,可以是本地R.drawable中的资源,也可以是Url
                .load(R.drawable.pear)
                //这里传递一个资源 ID ,xml文件中的ImageView的id
                .into(binding.actionImage)
        }
    }
}

 对应的XML文件为:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/actionImage"/>
    <Button
        android:id="@+id/inputPic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="take the pic"/>

</LinearLayout>

(2)加载Gif图片

通过 asGif() 指定传输Gif格式图片

class MainActivity : ComponentActivity() {

    private lateinit var binding:ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        super.onCreate(savedInstanceState)
        binding.inputPic.setOnClickListener{
            val options = RequestOptions.circleCropTransform()
            //设置图片
            Glide.with(this)
                .asGif()
                //设置图片资源的路径,可以是本地R.drawable中的资源,也可以是Url
                .load("url")
                .apply(options)
                //这里传递一个资源 ID ,xml文件中的ImageView的id
                .into(binding.actionImage)
        }
    }
}

(3)加载文件系统中的图片

GlideApp.with(context)
    .load(File("/path/to/image.jpg"))
    .into(imageView)


4、加载监听

如果需要监听加载状态,就需要实现 RequestListener 接口

class MainActivity : ComponentActivity() {

    private lateinit var binding:ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        super.onCreate(savedInstanceState)
        binding.inputPic.setOnClickListener{
            //设置图片
            Glide.with(this)
                //设置图片资源的路径,可以是本地R.drawable中的资源,也可以是Url
                .load(R.drawable.pear)
                .listener(object : RequestListener<Drawable> {

                    //加载失败的回调函数
                    override fun onLoadFailed(
                        e: GlideException?,
                        model: Any?,
                        target: Target<Drawable>?,
                        isFirstResource: Boolean
                    ): Boolean {
                        // 加载失败的处理逻辑
                        return false
                    }

                    //加载成功后的回调函数
                    override fun onResourceReady(
                        resource: Drawable?,
                        model: Any?,
                        target: Target<Drawable>?,
                        dataSource: DataSource?,
                        isFirstResource: Boolean
                    ): Boolean {
                       
                        // 资源加载成功时的处理逻辑
                        return false
                    }
                })
                //这里传递一个资源 ID ,xml文件中的ImageView的id
                .into(binding.actionImage)
        }
    }
}


 5、磁盘缓存策略

Glide的缓存机制设计是二级缓存:内存缓存默认开启的)、磁盘缓存

内存缓存和磁盘缓存不会相互影响是独立配置的

缓存的读取顺序设置:内存 ➡ 磁盘➡ 网络

内存缓存(一级缓存)和磁盘缓存(二级缓存)是两种不同的缓存机制,区别如下:

内存缓存(一级缓存):

  1. 快速访问:内存缓存存储在设备的 RAM 中,因此访问速度非常快,可以立即提供数据。
  2. 减少加载时间:对于频繁访问的数据,如图片或小的文本数据,内存缓存可以显著减少加载时间。
  3. 降低能耗:由于数据存储在内存中,访问这些数据不需要额外的磁盘I/O操作,从而降低了能耗。
  4. 易失性:当应用被关闭或系统内存不足时,内存缓存中的数据可能会被清除。
  5. 容量限制:内存缓存的容量受限于设备的 RAM 大小,因此不适合存储大量数据。
  6. 生命周期管理:内存缓存通常与应用的生命周期相关联,应用退出时缓存数据会被清除。

磁盘缓存(二级缓存):

  1. 持久性:磁盘缓存存储在设备的存储空间中,即使应用关闭或设备重启,数据仍然可以保留。
  2. 大容量存储:磁盘缓存可以存储比内存缓存更多的数据,适合存储大文件或大量数据。
  3. 访问速度较慢:与内存相比,磁盘的读取速度较慢,因此访问磁盘缓存中的数据需要更长的时间。
  4. 非易失性:磁盘缓存的数据不会因为应用关闭而丢失,适合存储需要长期保留的数据。
  5. 管理成本:磁盘缓存需要开发者或缓存机制来管理,包括缓存的清理和过期策略。
  6. 适合离线使用:由于数据存储在本地,磁盘缓存可以在没有网络连接的情况下访问数据,适合离线应用。
  7. 生命周期更长:磁盘缓存的数据可以跨越应用会话,甚至在应用卸载后仍然保留(除非手动清理或系统清理)。

在实际应用中,内存缓存和磁盘缓存通常会结合使用,以提供最佳的性能和用户体验:

  • 内存缓存用于快速访问最近或频繁使用的数据。
  • 磁盘缓存用于存储不经常访问但需要长期保留的数据。

Glide 提供了5种磁盘缓存策略,用来控制图片如何被存储在磁盘上:

DiskCacheStrategy.ALL:缓存原始图片和转换后的图片
DiskCacheStrategy.NONE:不缓存任何图片
DiskCacheStrategy.RESOURCE:只缓存转换后的图片
DiskCacheStrategy.DATA:只缓存原始图片
DiskCacheStrategy.ORIGINAL_KEY:使用原始的图片 URL 作为缓存键

使用示例:

GlideApp.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.ALL) // 缓存原始和转换后的图片
    .into(imageView)

GlideApp.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.NONE) // 不缓存图片
    .into(imageView)

GlideApp.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.RESOURCE) // 只缓存转换后的图片
    .into(imageView)

GlideApp.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.DATA) // 只缓存原始图片
    .into(imageView)

GlideApp.with(context)
    .load(url)
    .diskCacheStrategy(DiskCacheStrategy.ORIGINAL_KEY) // 使用原始 URL 作为缓存键
    .into(imageView)


 6、常用配置选项

(1)设置占位符

占位符的作用是在图片加载完成之前显示一个占位符图片

val options = RequestOptions.placeholderOf(R.drawable.placeholder)
Glide.with(context)
    .setDefaultRequestOptions(options)
    .load(url)
    .into(imageView)

(2)设置错误图片

如果图片加载失败,则会显示一个提前设置好的错误图片。

val options = RequestOptions.errorOf(R.drawable.error)
Glide.with(context)
    .setDefaultRequestOptions(options)
    .load(url)
    .into(imageView)

(3)设置后备图片

如果图片加载的所有来源失败,则显示后备图片

val options = RequestOptions.fallbackOnDrawable(R.drawable.fallback)
Glide.with(context)
    .setDefaultRequestOptions(options)
    .load(url)
    .into(imageView)

(4)覆盖图片尺寸

强制图片以特定的尺寸加载,忽略原始图片的尺寸

val options = RequestOptions.overrideOf(100, 200) // 宽度和高度
Glide.with(context)
    .load(url)
    .apply(options)
    .into(imageView)

(5)中心裁剪

将图片缩放并裁剪,使其填充整个ImageView,同时保持图片的中心部分

val options = RequestOptions.centerCropTransform(context)
Glide.with(context)
    .load(url)
    .apply(options)
    .into(imageView)

(6)适应中心

将图片缩放以适应ImageView,同时保持宽高比,并在ImageView中居中显示

val options = RequestOptions.fitCenterTransform()
Glide.with(context)
    .load(url)
    .apply(options)
    .into(imageView)

(7)圆形裁剪

将图片裁剪成一个圆形

val options = RequestOptions.circleCropTransform()
Glide.with(context)
    .load(url)
    .apply(options)
    .into(imageView)

(8)应用自定义变换

自定义的 Transformation 是一个功能强大的工具,它允许对加载的图片进行各种变换处理。这个接口提供了一个方法,可以在这个方法中对 Bitmap 进行任意的修改,比如改变尺寸、应用滤镜效果、调整颜色或者裁剪成特定的形状

自定义 Transformation 的使用步骤通常如下:

  1. 创建 Transformation 子类:创建一个新的类继承自 BitmapTransformation 或 Transformation 接口。
  2. 重写 transform 方法:实现 transform 方法,该方法接收一个 Bitmap 对象,并返回一个修改后的 Bitmap 对象。
  3. 更新 ID:如果你想要 Glide 缓存经过此变换的图片,你需要重写 equals 和 hashCode 方法,以确保不同的变换实例能被正确识别。
  4. 使用 Transformation:将你的自定义 Transformation 实例应用到图片加载请求中。
val options = RequestOptions.bitmapTransform(CropCircleTransformation())
Glide.with(context)
    .load(url)
    .apply(options)
    .into(imageView)

(9)设置加载优先级

val options = RequestOptions.priorityOf(Priority.HIGH)
Glide.with(context)
    .setDefaultRequestOptions(options)
    .load(url)
    .into(imageView)

(10)跳过内存缓存

强制请求跳过内存缓存,直接从磁盘或网络加载图片

val options = RequestOptions.skipMemoryCacheOf(true)
Glide.with(context)
       .load(url)
       .apply(options)
       .into(imageView)

 (11)组合多个选项

通过链式调用,组合多个 RequestOption,一次性设置多个配置选项

val options = RequestOptions()
    .placeholder(R.drawable.placeholder)
    .error(R.drawable.error)
    .fitCenter()

Glide.with(context)
       .setDefaultRequestOptions(options)
       .load(url)
       .into(imageView)

(12)查看数据源

Glide.with(this)
.load(ConstUrl.ImgOne)
.apply(optionInto)
.listener(object : RequestListener<Drawable> {
    override fun onLoadFailed(e: GlideException?, model: Any?, 
target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
        Log.i(TAG, "onLoadFailed: ")
        return false
    }

    override fun onResourceReady(resource: Drawable?, model: Any?, target:
 Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
        Log.i(TAG, "onResourceReady: $dataSource")
        return false
    }
})
.into(iv)

Glide判断是否是缓存的依据就是判断回调函数中的参数:dataSource

dataSource)数据源说明
LOCAL本地文件
REMOTE远程链接
DATA_DISK_CACHE原始硬盘缓存
RESOURCE_DISK_CACHE转换后的硬盘缓存
MEMORY_CACHE内存缓存

 

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐