Glide4用法全解析

3,602 阅读7分钟

使用准备

添加依赖

implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'

权限

<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" />

ACCESS_NETWORK_STATE 对于 Glide 加载 URL 并不是必需的,但是它将帮助 Glide 处理 片状网络(flaky network) 和飞行模式。如果你正在从 URL 加载图片,Glide 可以自动帮助你处理片状网络连接:它可以监听用户的连接状态并在用户重新连接到网络时重启之前失败的请求。如果 Glide 检测到你的应用拥有 ACCESS_NETWORK_STATE 权限,Glide 将自动监听连接状态而不需要额外的改动

如果要使用 ExternalPreferredCacheDiskCacheFactory 来将 Glide 的缓存存储到公有 SD 卡上,就需要添加 WRITE_EXTERNAL_STORAGE 权限。

混淆

-dontwarn com.bumptech.glide.**
-keep class com.bumptech.glide.**{*;}
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

Kotlin

如果你在 Kotlin 编写的类里使用 Glide 注解,你需要引入一个 kapt 依赖,以代替常规的 annotationProcessor 依赖:

dependencies {
  kapt 'com.github.bumptech.glide:compiler:4.8.0'
}

还需要在你的 build.gradle 文件中包含 kotlin-kapt插件: apply plugin: 'kotlin-kapt'

RequestBuilder

RequestBuilder是Glide中请求的骨架,负责携带请求的url和你的设置项来开始一个新的加载过程。 RequestBuilder的来源如下:

RequestBuilder<Drawable> requestBuilder = Glide.with(fragment).asDrawable();
RequestBuilder<Drawable> requestBuilder = Glide.with(fragment).load("url");
RequestBuilder<Bitmap> requestBuilder = Glide.with(fragment).asBitmap();
RequestBuilder<GifDrawable> requestBuilder = Glide.with(fragment).asGif();
RequestBuilder<File> requestBuilder = Glide.with(fragment).asFile();

使用

 Glide.with(this)
    .load("url")
    .apply()//设置请求选项
    .transition()//设置过渡
    .thumbnail()//略缩图相关
    .error()//请求出错相关
    .listener()或addListener//监听
    .into()或submit()//指定目标

RequestOptions

RequestOptions cropOptions = new RequestOptions().centerCrop();
Glide.with(fragment)
    .load(url)
    .apply(cropOptions)
    .into(imageView);

RequestOptions用来提供独立的选项来定制Glide加载。由于apply() 方法可以被调用多次,因此 RequestOption 可以被组合使用。如果 RequestOptions 对象之间存在相互冲突的设置,那么只有最后一个被应用的 RequestOptions 会生效。

常用的api如下:

占位图

占位符是当请求正在执行时被展示的 Drawable 。当请求成功完成时,占位符会被请求到的资源替换

  • placeholder():占位图,如果请求失败并且没有设置 error Drawable ,则占位符将被持续展示
  • error():异常占位图,在请求永久性失败时展示
  • fallback:后备回调符,在请求的url为 null 时展示

设计 fallback Drawable 的主要目的是允许用户指示 null 是否为可接受的正常情况。例如,一个 null 的个人资料 url 可能暗示这个用户没有设置头像,因此应该使用默认头像。然而,null 也可能表明这个元数据根本就是不合法的,或者取不到。 默认情况下Glide将 null 作为错误处理,所以可以接受 null 的应用应当显式地设置一个 fallback Drawable 。

//placeholder()
Glide.with(fragment)
  .load(url)
  .placeholder(R.drawable.placeholder)
//.placeholder(new ColorDrawable(Color.BLACK))
  .into(view);

//error()
Glide.with(fragment)
  .load(url)
  .error(R.drawable.error)
//.error(new ColorDrawable(Color.RED))
  .into(view);

//fallback
Glide.with(fragment)
  .load(url)
  .fallback(R.drawable.fallback)
//.fallback(new ColorDrawable(Color.GREY))
  .into(view);

注意:

  • 占位符是在主线程从Android Resources加载的
  • 变换不会被应用到占位符上
  • 在多个不同的View上可以使用相同的无状态的Drawable;但是有状态的 Drawable 不一样,在同一时间多个 View 上展示它们通常不是很安全,因为多个View会立刻修改(mutate) Drawable 。对于有状态的 Drawable ,建议传入一个资源ID,或者使用 newDrawable() 来给每个请求传入一个新的拷贝。

diskCacheStrategy()

用来设置硬盘缓存,可选项如下:

  • DiskCacheStrategy.NONE: 表示不缓存任何内容。
  • DiskCacheStrategy.DATA: 表示只缓存原始图片。
  • DiskCacheStrategy.RESOURCE: 表示只缓存转换过后的图片。
  • DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。
  • DiskCacheStrategy.AUTOMATIC:表示让Glide根据图片资源智能地选择使用哪一种缓存策略(默认选项)

skipMemoryCache(boolean)

  • true :跳过内存缓存
  • false :不跳过内存缓存

变换

默认变换

  • centerCrop():以填满整个控件为目标,等比缩放,超过控件时将被 裁剪 ( 宽高都要填满 ,所以只要图片宽高比与控件宽高比不同时,一定会被剪裁)
  • centerInside():以完整显示图片为目标, 不剪裁 ,当显示不下的时候将缩放,能够显示的情况下不缩放
  • fitCenter():将图片按照原始的长宽比充满全屏
  • circleCrop():圆形裁剪
  • transform():设置自定义图片变换

optionalCenterCrop()optionalCenterInside()optionalFitCenter()optionalCircleCrop()centerCrop()centerInside()fitCenter()circleCrop()的区别:centerCrop()等对未知类型图片进行变换时会抛出异常,而optionalCenterCrop()则会忽略未知的图片类型。

多重变换

transform(new MultiTransformation<>(new CenterCrop(),new CircleCrop()))
transforms(new CenterCrop(),new CircleCrop())

传入变换参数的顺序,决定了这些变换的应用顺序

自定义变换

自定义变换需要继承BitmapTransformation(也可以继承Transformation),并重写下面方法:

equals
hashCode
updateDiskCacheKey
transform

下面是CircleCrop的源码

public class CircleCrop extends BitmapTransformation {
  private static final int VERSION = 1;
  private static final String ID = "com.bumptech.glide.load.resource.bitmap.CircleCrop." + VERSION;
  private static final byte[] ID_BYTES = ID.getBytes(CHARSET);

  // Bitmap doesn't implement equals, so == and .equals are equivalent here.
  @SuppressWarnings("PMD.CompareObjectsWithEquals")
  @Override
  protected Bitmap transform(
      @NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
    return TransformationUtils.circleCrop(pool, toTransform, outWidth, outHeight);
  }

  @Override
  public boolean equals(Object o) {
    return o instanceof CircleCrop;
  }

  @Override
  public int hashCode() {
    return ID.hashCode();
  }

  @Override
  public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
    messageDigest.update(ID_BYTES);
  }
}

glide-transformations是一个优秀的自定义变换库,该库的效果如图

override()

用来指定了一个图片的尺寸(单位px),可以用Target.SIZE_ORIGINAL表示加载原始尺寸的图片,但这会产生OOM的风险。

TransitionOptions

TransitionOptions 用于决定你的加载完成时从占位图到目标图过渡之间会发生什么。

不同于 Glide v3,Glide v4 将不会默认应用交叉淡入或任何其他的过渡效果。每个请求必须手动应用过渡。

Glide.with(this)
    .load("")
    .transition(DrawableTransitionOptions.withCrossFade())
    .into(imageView);
  • GenericTransitionOptions:通用的过渡选项
  • DrawableTransitionOptions:只应用于Glide调用了asDrawable()(默认)方法时,才能使用
  • BitmapTransitionOptions:只应用于Glide调用asBitmap()方法时,才能使用

Glide中只实现了淡入淡出的过渡效果,即调用DrawableTransitionOptionsBitmapTransitionOptionswithCrossFade()方法,如果需要自定义过渡效果,则必需实现TransitionFactory ,并且 使用 DrawableTransitionOptionsBitmapTransitionOptionswith方法来将你自定义的 TransitionFactory 应用到加载中。

略缩图(thumbnail)

//thumbnail()方法可以简单快速地加载图像的低分辨率版本,并且同时加载图像的无损版本
Glide.with(this)
    .asDrawable()
    .load("url")
    .thumbnail(Glide.with(this).load("thumbnailUrl"))
    .into(imageView);
//加载同一个图片,但尺寸为 View 或 Target 的某个百分比的(这里为0.25)
Glide.with(this)
    .asDrawable()
    .load("url")
    .thumbnail(0.25f)
    .into(imageView);

error

Glide.with(fragment)
  .load("url")
  .error(Glide.with(fragment)
      .load("errorUrl"))
  .into(imageView);

在失败时开始新的请求。如果主请求成功完成,则这个error请求 将不会被启动。如果你同时指定了一个 thumbnail() 和一个 error请求,则这个后备的 error请求将在主请求失败时启动,即使缩略图请求成功也是如此。

listener和addListener

Glide.with(this)
    .load("url")
    .listener(new RequestListener<Drawable>() {
        @Override
        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
            return false;
        }

        @Override
        public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
            return false;
        }
    })
    .into(imageView);

RequestListener需要实现两个方法,一个onResourceReady()方法,一个onLoadFailed()方法。当图片加载完成的时候就会回调onResourceReady()方法,而当图片加载失败的时候就会回调onLoadFailed()方法。onResourceReady()方法和onLoadFailed()方法都有一个布尔值的返回值,返回false就表示这个事件没有被处理,还会继续向下传递,返回true就表示这个事件已经被处理掉了,从而不会再继续向下传递。

与Glide的listener类似的还有一个addListener方法,它们的区别在于,当调用多个listener方法时,只会调用最后的listener回调;而addListener方法会依次调用多个addListener设置的回调。

into和submit

  • into():下载图片,并把资源加载到指定目标上
  • submit():只会下载图片,而不会对图片进行加载

调用了submit()方法后会立即返回一个FutureTarget对象,然后Glide会在后台开始下载图片文件。之后我们调用FutureTargetget()方法就可以去获取下载好的图片文件了,注意:get()方法会阻塞当前线程,直到下载完成

参考