Glide介绍及基本使用方法

Posted weixin_49078536

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Glide介绍及基本使用方法相关的知识,希望对你有一定的参考价值。

官方介绍

关于 Glide

Glide是一个快速高效的android图片加载库,注重于平滑的滚动。Glide提供了易用的API,高性能、可扩展的图片解码管道(decode pipeline),以及自动的资源池技术。

Glide 支持拉取,解码和展示视频快照,图片,和GIF动画。Glide的Api是如此的灵活,开发者甚至可以插入和替换成自己喜爱的任何网络栈。默认情况下,Glide使用的是一个定制化的基于HttpUrlConnection的栈,但同时也提供了与Google Volley和Square OkHttp快速集成的工具库。

虽然Glide 的主要目标是让任何形式的图片列表的滚动尽可能地变得更快、更平滑,但实际上,Glide几乎能满足你对远程图片的拉取/缩放/显示的一切需求。

性能

Glide 充分考虑了Android图片加载性能的两个关键方面:

  • 图片解码速度
  • 解码图片带来的资源压力

为了让用户拥有良好的App使用体验,图片不仅要快速加载,而且还不能因为过多的主线程I/O或频繁的垃圾回收导致页面的闪烁和抖动现象。

Glide使用了多个步骤来确保在Android上加载图片尽可能的快速和平滑:

  • 自动、智能地下采样(downsampling)和缓存(caching),以最小化存储开销和解码次数;
  • 积极的资源重用,例如字节数组和Bitmap,以最小化昂贵的垃圾回收和堆碎片影响;
  • 深度的生命周期集成,以确保仅优先处理活跃的Fragment和Activity的请求,并有利于应用在必要时释放资源以避免在后台时被杀掉。

环境配置

Gradle依赖

在gradle里依赖,目前最新版本为4.12.0

implementation 'com.git`hub.bumptech.glide:glide:4.12.0'`

Glide 支持 Maven 项目,依赖方法:

<dependency>
<groupId>com.github.bumptech.glide</groupId>
<artifactId>glide</artifactId>
<version>4.12.0</version>
<type>aar</type>
</dependency>

AndroidManifest.xml 中添加权限设置

按项目需求进行添加

    <!-- 网络权限 -->
    <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" />

基本用法

Glide 库是使用流接口(fluent interface)。对一个完整的功能请求,Glide 建造者要求最少有三个参数。

//加载图片
Glide.with(context)
    .load(url)
    .into(imageView);

//取消加载
Glide.with(context).clear(imageView);

context :可以传入fragment 、activity 和applicationContext 等。
load :图片资源。可以是resourceId 、url 、uri 、drawable 、file 等。
into :图片会显示到对应的 ImageView 中

取消加载并非是必要的操作,在Glide.with()中传入的context如果是activity或fragment,当它们的实例销毁时,Glide 会自动取消加载并回收资源。

小拓展:
resourceID转换为Uri的方法

private static Uri resourceIdToUri(Context context, int resourceId) 
    return Uri.parse("android.resource://" + context.getPackageName()
     + "/" + resourceId);


占位符

Glide允许用户指定三种不同类型的占位符,分别在三种不同场景使用。他们分别是placeholder,error和falllback。

placeholder(占位符)

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

Glide.with(context)
  .load(url)
  .placeholder(R.drawable.placeholder)
  .into(view);

error(错误符)

error Drawable 在请求永久性失败时展示。
error()接受的参数只能是已经初始化的 drawable 对象或者指明它的资源(R.drawable.xxx)

Glide.with(context)
  .load(url)
  .error(R.drawable.error)
  .into(view);

fallback(后备回调符)

fallback Drawable 在请求的url为 null 时展示。

Glide.with(context)
  .load(url)
  .fallback(R.drawable.fallback)
  .into(view);

当Gilde.load()中传入的资源为null,或者是无法成功获取时,展示优先级为fallback > error > placeholder。
占位符都是独立的,可以根据开发需要来调用。除基本用法中的三个方法,Glide的其他方法也是如此。
占位符是在主线程从Android Resources加载的。占位符应当比较小且容易被系统资源缓存机制缓存起来。

提示:多个不同的View上可以使用相同的Drawable,但仅限于无状态的drawable(例如Bitmap)。但是有状态的 Drawable 不一样,在同一时间多个 View 上展示它们通常不是很安全,因为多个View会立刻修改(mutate) Drawable 。对于有状态的 Drawable ,建议传入一个资源ID,或者使用 newDrawable() 来给每个请求传入一个新的拷贝。


选项

请求选项

Glide中的大部分设置项都可以直接应用在 Glide.with() 返回的 RequestBuilder 对象上。

可用的选项包括但不限于:

  • 占位符(Placeholders)
  • 转换(Transformations)
  • 缓存策略(Caching Strategies)
  • 组件特有的设置项,例如编码质量,或Bitmap的解码配置等。

如果想让应用的不同部分之间共享相同的加载选项,可以初始化一个新的 RequestOptions 对象,并在每次加载时通过 apply() 方法传入这个对象:

RequestOptions cropOptions = new RequestOptions().centerCrop(context);

Glide.with(context)
    .load(url)
    .apply(cropOptions)
    .into(imageView);

apply() 方法可以被调用多次,因此 RequestOption 可以被组合使用。如果 RequestOptions 对象之间存在相互冲突的设置,那么只有最后一个被应用的 RequestOptions 会生效。

过渡选项

TransitionOptions 用于决定加载完成时会发生什么。

使用 TransitionOption 可以应用以下变换:

  • View淡入
  • 与占位符交叉淡入
  • 或者什么都不发生

如果不使用变换,你图像将会直接出现在其显示位置,替换掉之前的图像。为了避免这种突然的改变,可以淡入view,或者让多个Drawable交叉淡入,而这些都需要使用TransitionOptions完成。

例如,要应用一个交叉淡入变换:

import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
//import com.bumptech.glide.GenericTransitionOptions.withNoTransition

Glide.with(fragment)
    .load(url)
    .transition(withCrossFade())
//    不发生变换
//    .transition(withNoTransition())
    .into(view);

不同于RequestOptions,TransitionOptions是特定资源类型独有的,假如请求加载一个 Bitmap ,需要使用 BitmapTransitionOptions ,而不是 DrawableTransitionOptions 。

RequestBuilder

使用 RequestBuilder 可以指定:

  • 加载的资源类型(Bitmap, Drawable, 或其他)
  • 加载的资源地址(url/model)
  • 最终加载到的View
  • 想应用的(一个或多个)RequestOption 对象
  • 想应用的(一个或多个)TransitionOption 对象
  • 想加载的缩略图 thumbnail()
    要构造一个 RequestBuilder 对象,可以通过先调用 Glide.with()然后再调用某一个 as 方法来完成:
RequestBuilder<Drawable> requestBuilder = Glide.with(fragment).asDrawable();

或先调用 Glide.with() 然后 load():

RequestBuilder<Drawable> requestBuilder = Glide.with(fragment).load(url);
选择资源类型

RequestBuilders 是特定于它们将要加载的资源类型的。默认情况下会得到一个 Drawable RequestBuilder ,但可以使用 as… 方法来改变请求类型。

应用 RequestOptions

前面提到,可以使用 apply() 方法应用 RequestOptions ,使用 transition() 方法应用 TransitionOptions 。

RequestBuilder<Drawable> requestBuilder = Glide.with(fragment).asDrawable();
  requestBuilder.apply(requestOptions);
  requestBuilder.transition(transitionOptions);
缩略图 (Thumbnail) 请求

Glide 的 thumbnail() API 允许指定一个 RequestBuilder 以与你的主请求并行启动。
thumbnail() 会在主请求加载过程中展示。如果主请求在缩略图请求之前完成,则缩略图请求中的图像将不会被展示。thumbnail() API 允许简单快速地加载图像的低分辨率版本,并且同时加载图像的无损版本。

Glide.with(context)
  .load(url)
  .thumbnail(Glide.with(context).load(thumbnailUrl))
  .into(imageView);

在只有url而没有thumbnailUrl的情况下,可以使用override方法。

Glide.with(context)
  .load(url)
  .thumbnail(Glide.with(context)
    .load(url)
//    .override(int width, int height)
    .override(int thumbnailSize))
  .into(view);

thumbnail() 方法有一个简化版本,它只需要一个 sizeMultiplier 参数

Glide.with(context)
  .load(url)
  .thumbnail(/*sizeMultiplier=*/ 0.1f)
  .into(imageView);
在失败时开始新的请求

在 error 方法里 来指定一个 RequestBuilder,可以在主请求失败时开始一次新的加载。

Glide.with(context)
  .load(primaryUrl)
  .error(Glide.with(context)
      .load(fallbackUrl))
  .into(imageView);

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

请求的优先级

Priority枚举给了四个不同的选项,下面是按照递增priority(优先级)的列表:

Priority.LOW
Priority.NORMAL
Priority.HIGH
Priority.IMMEDIATE

优先级并不是完全严格遵守的。Glide 将会用他们作为一个准则,并尽可能的处理这些请求,但是它不能保证所有的图片都会按照所要求的顺序加载。

Glide.with(context)
  .load(url)
  .priority(Priority.HIGH)
  .into(imageView);

组件选项

Option 类是给Glide的组件添加参数的通用办法,包括 ModelLoaders , ResourceDecoders , ResourceEncoders , Encoders 等等。一些Glide的内置组件提供了设置项,自定义的组件也可以添加设置项。

Option 通过 RequestOptions 类应用到请求上:

Glide.with(context)
  .load(url)
  .option(MyCustomModelLoader.TIMEOUT_MS, 1000L)
  .into(imageView);

变换

在Glide中,Transformations 可以获取资源并修改它,然后返回被修改后的资源。通常变换操作是用来完成剪裁或对位图应用过滤器,但它也可以用于转换GIF动画,甚至自定义的资源类型。

内置类型

Glide 提供了很多内置的变换,包括:

  • CenterCrop
  • FitCenter
  • CircleCrop

应用

CenterCrop

CenterCrop()是一个裁剪技术,即缩放图像让它填充到 ImageView 界限内并且裁剪额外的部分。ImageView 可能会完全填充,但图像可能不会完整显示。

Glide.with(context)
  .load(url)
  .centerCrop()
  .into(imageView)

或使用 RequestOptions

RequestOptions options = new RequestOptions();
options.centerCrop();

Glide.with(context)
    .load(url)
    .apply(options)
    .into(imageView);
FitCenter

fitCenter() ,即缩放图像让图像都测量出来等于或小于 ImageView 的边界范围。该图像将会完全显示,但可能不会填满整个 ImageView。

Glide.with(context)
  .load(url)
  .fitCenter()
  .into(imageView)
CircleCrop

CircleCrop()和fitCenter()行为类型,但会剪裁出圆形图片。

Glide.with(context)
  .load(url)
  .circleCrop()
  .into(imageView)

Transformations

添加依赖

compile 'jp.wasabeef:glide-transformations:4.0.0'
//使用GPU转换
compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:xxxx'

多重变换

默认情况下,每个 transform() 调用,或任何特定转换方法的调用都会替换掉之前的变换。

如果想在单次加载中应用多个变换,请使用 MultiTransformation 类,或其快捷方法 .transforms() 。

Glide.with(context)
  .load(url)
//   MultiTransformation 类
//  .transform(new MultiTransformation(new FitCenter(), new YourCustomTransformation())

// 快捷方法
  .transform(new FitCenter(), new YourCustomTransformation())
  .into(imageView);

向 MultiTransformation 的构造器传入变换参数的顺序,决定了这些变换的应用顺序。

自定义变换

一个简单的BitmapTransformation

如果只需要变换 Bitmap,最好是从继承 BitmapTransformation 开始。BitmapTransformation 为我们处理了一些基础的东西,例如,如果变换返回了一个新修改的 Bitmap ,BitmapTransformation将负责提取和回收原始的 Bitmap。

public class FillSpace extends BitmapTransformation 
    private static final String ID = "com.bumptech.glide.transformations.FillSpace";
    private static final String ID_BYTES = ID.getBytes(STRING_CHARSET_NAME);

    @Override
    public Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) 
        if (toTransform.getWidth() == outWidth && toTransform.getHeight() == outHeight) 
            return toTransform;
        

        return Bitmap.createScaledBitmap(toTransform, outWidth, outHeight, /*filter=*/ true);
    

    @Override
    public void updateDiskCacheKey(MessageDigest messageDigest)
        throws UnsupportedEncodingException 
      messageDigest.update(ID_BYTES);
    
    
    @Override
    public void equals(Object o) 
      return o instanceof FillSpace;
    

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

使用这个BitmapTransformation

Glide 有两种方式去使用转换。首先是传一个类的实例作为参数给 .transform()。这里可以使用任何转换,无论它是否是用于图像还是 Gif。其他选择是使用 .bitmapTransform(),它只能用于 bitmap 的转换。因为我们上面的实现是为 bitmap 设计的,这两者我们都可以用:

Glide  
    .with(context)
    .load(url)
    .transform(new FillSpace())
    //.bitmapTransform(new FillSpace()) // this would work too!
    .into( imageView );

注意

请特别注意,对于任何 Transformation 子类,包括 BitmapTransformation,有三个方法 必须 实现它们,以使得磁盘和内存缓存正确地工作。如果没有复写equals()和hashCode(),BitmapTransformation 和 Transformation 也能通过编译,但这并不意味着它们能正常工作。

ImageView的自动变换

在Glide中,当一个 ImageView 开始加载时,Glide可能会自动应用 FitCenter 或 CenterCrop ,这取决于view的 ScaleType 。如果 scaleType 是 CENTER_CROP , Glide 将会自动应用 CenterCrop 变换。如果 scaleType 为 FIT_CENTER 或 CENTER_INSIDE ,Glide会自动使用 FitCenter 变换。

我们可以覆写默认的变换,只需要一个带有 Transformation 集合的 RequestOptions 即可。另外也可以通过使用 dontTransform() 确保不会自动应用任何变换。


目标

关于Target

在Glide中,Target 是介于请求和请求者之间的中介者的角色。Target 负责展示占位符,加载资源,并为每个请求决定合适的尺寸。被使用得最频繁的是 ImageViewTargets ,它用于在 ImageView 上展示占位符、Drawable 和 Bitmap 。

指定目标

into(Target) 方法不仅仅用于启动每个请求,它同时也指定了接收请求结果的 Target:

Target<Drawable> target = 
  Glide.with(context)
    .load(url)
    .into(new Target<Drawable>() 
      ...
    );

Glide 提供了一个辅助方法 into(ImageView) ,它接受一个 ImageView 参数并为其请求的资源类型包装了一个合适的 ImageViewTarget:

Target<Drawable> target = 
  Glide.with(context)
    .load(url)
    .into(imageView);

取消和重用

into(Target) 和 into(ImageView) 都返回了一个 Target 实例。重用这个 Target 来在将来开始一个新的加载,之前开始的任何请求都会被取消,它们使用的资源将被释放。
也可以使用返回的 Target 来 clear() 之前的加载,这将在不需要开始新的加载的情况下释放掉相关资源。

Target<Drawable> target = 
  Glide.with(fragment)
    .load(url)
    .into(new Target<Drawable>() 
      ...
    );
... 
// Some time in the future:
Glide.with(context)
  .load(newUrl)
  .into(target);
  
// Some time in the future:
Glide.with(context).clear(target);

//与加载到imageView类似
Glide.with(context)
  .load(newUrl)
  .into(imageView);
Glide.with(context).clear(imageView);

SimpleTarget

指定尺寸
SimpleTarget target = new SimpleTarget<Bitmap>( 250, 250 )   
    @Override
    public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) 
        imageView.setImageBitmap( bitmap );
    
;

 Glide.with( context.getApplicationContext() ) // safer!
      .load( url )
      .asBitmap()
      .into( target );

动画资源
Glide.with(context)
  .load(url)
  .into(new SimpleTarget<>() 
    @Override
    public void onResourceReady(Drawable resource, Transition<GifDrawable> transition) 
      if (resource instanceof Animatable) 
        resource.start();
      
      // Set the resource wherever you need to use it.
    
  );

ViewTarget

Glide 并不支持加载图片到自定义 view 中,所以可以使用ViewTarget 来实现。

     CustomView customView = (CustomView) findViewById( R.id.custom_view );

    viewTarget = new ViewTarget<CustomView, GlideDrawable>( customView ) 
        @Override
        public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) 
            //view.setImag是自定义view里自己去实现的方法
            this.view.setImage( resource.getCurrent() );
        
    ;

    Glide
        .with( context) 
        .load( url )
        .into( viewTarget );

Target下载图片文件

val future: FutureTarget<File> = Glide.with(context)
                .load(url)
                .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
val cacheFile: File = future.get()

清理

当你完成了对资源的使用时,需要及时清理创建的这些 Target 。即使请求已经完成了,也应该使用 clear() 以使 Glide 可以重用被这次加载使用的资源 (特别是 Bitmap )。未调用 clear() 会浪费 CPU 和内存,阻塞更重要的加载,甚至如果你在同一个 surface (View, Notification, RPC 等) 上有两个 Target,可能会引发图片显示错误。对于像 SimpleTarget这种无法从一个新实例里跟踪前一个请求的 Target 来说,及时清理尤为重要。


缓存

默认情况下,Glide 会在开始一个新的图片请求之前检查以下多级的缓存:

1.活动资源 (Active Resources) - 现在是否有另一个 View 正在展示这张图片
2.内存缓存 (Memory cache) - 该图片是否最近被加载过并仍存在于内存中
3.资源类型(Resource) - 该图片是否之前曾被解码、转换并写入过磁盘缓存
4.数据来源 (Data) - 构建这个图片的资源是否之前曾被写入过文件缓存

前两步检查图片是否在内存中,如果是则直接返回图片。
后两步则检查图片是否在磁盘上,以便快速但异步地返回图片。

如果四个步骤都未能找到图片,则Glide会返回到原始资源以取回数据(原始文件,Uri, Url等)。

磁盘缓存策略

DiskCacheStrategy 可被 diskCacheStrategy 方法应用到每一个单独的请求。

DiskCacheStrategy.NONE -------------什么都不缓存
DiskCacheStrategy.DATA ------------- 仅仅只缓存原来的全分辨率的图像。
DiskCacheStrategy.RESOURCE -----仅仅缓存最终的图像,即,降低分辨率后的(或者是转换后的)
DiskCacheStrategy.ALL ----------------缓存所有版本的图像
DiskCacheStrategy.AUTOMATIC ----让Glide根据图片资源智能地选择使用哪一种缓存策略(默认选项

跳过磁盘缓存

Glide.with(context)
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.NONE)
  .into(view);

跳过内存缓存

Glide.with(context)
  .load(url)
  .skipMemoryCache(true)
  .into(view);

仅从缓存加载图片

省流模式下可以使用此方法

Glide.with(context)
  .load(url)
  .onlyRetrieveFromCache(true)
  .into(imageView);

清理缓存

Glide.get(context).clearDiskCache();//只能在子线程执行
Glide.get(context).clearMemory(<

一起Talk Android吧(第四百回:Glide的基本用法)

文章目录

各位看官们,大家好,上一回中咱们说的是"获取Bitmap的方法总结"的例子,这一回中咱们介绍的例子是"Glide的基本用法"。闲话休提,言归正转,让我们一起Talk Android吧!

看官们,我们在本章回中将介绍第三方图片加载库:Glide。它是Android中经常使用的图片加载库,而且也是Google官方推荐的图片加载库。

背景知识

Glide是一个开源的图片加载库,大家可以到Github中查看其源代码。它提供了从本地、网络等多种渠道来加载图片,而且性能非常好,同时可以对图片进行缩放。它还提供异步操作,可以在后台加载图片。这些只是我自己的总结,更加详细的用法可以参考官方文档(热心的网友还将其翻译成了中文文档

使用方法

接下来我们通过文字结合代码的方法来介绍Glide的基本使用方法。

  • 1.添加依赖
    在模块的builde.gradle添加库的依赖:
   implementation 'com.github.bumptech.glide:glide:4.14.2'

在项目中可以对缓冲大小等内容做适当的配置,这样可以优化配置以使用它发挥更好的性能,具体的配置方法可以参考官方文档。

  • 2.创建ImageView组件
    在项目中创建一个ImageView组件,并且对其进行初始化,详细代码如下:
//使用ViewBinding,xml布局中的内容暂时省略
mBinding = ActivityGirdLayoutTestBinding.inflate(getLayoutInflater());
setContentView(mBinding.getRoot());
//使用ViewBinding来加载布局中的ImageView组件
mImageView = mBinding.idImageview;
  • 3.加载图片并且将其显示到ImageVeiw上
Glide.with(this)
        .load(R.drawable.ic_drag_size)
        .into(mImageView);
  • 4.对图片进行缩放(缩放和加载时同时进行)
Glide.with(this)
        .load(R.drawable.ic_drag_size)
        .override(200,200)
        .into(mImageView);

在上面的代码中,我们通过With方法来创建Glide对象,然后使用它的Load()方法来从Drawable资源中加载图片,最后通过inot()方法将图片显示到ImageView上。这些方法可以连续使用,因此整体的代码看上去非常的简洁。

with方法是重载方法,其参数可以是Activity或者Fragment。
load方法也是重载方法,它的参数可以是Uri对象,File对象,资源ID,以及更加能通用的String对象。我们可以使用不同的重载方法加载本地或者网络中的图片,与BitmapFactory类中的方法相比,它只使用一个重载方法来加载图片,而不是使用多个方法来加载图片。除了这三个基本的方法外,还可以使用override()方法对图片进行大小缩放。

关于Glide的用法比较多,我们在这里只介绍它的基本使用方法,其它的使用细节可以参考官方文档。

看官们,关于Android中"Glide的基本用法"的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

以上是关于Glide介绍及基本使用方法的主要内容,如果未能解决你的问题,请参考以下文章

Android Glide图片框架的使用

Android Glide图片框架的使用

[golang] Glide 包管理

Glide-源码详解

Glide-源码详解

Glide使用及原理概述