一、简介

Glide是一个加载图片的库,作者是bumptech。是google推荐使用的图片加载库。

特性:
1、可以从多个源加载图片,如:网路,本地,Uri等。
2、可以加载gif图片。Picasso不能加载git图片
3、生命周期和Activity/Fragment一致。
3、默认Bitmap格式是PREFER_ARGB_8888,Glide4.0之前是PREFER_RGB_565

二、使用

1、引入glide

//Glide框架引入
implementation ‘com.github.bumptech.glide:glide:4.9.0’
annotationProcessor ‘com.github.bumptech.glide:compiler:4.9.0’

2、加载图片
Glide.with(this)
    .load(IMG_PATH)
    .into(imageView);

就这样一句话就可以将图片加载出来了。除此之外还有一些其他的配置。

<1> 加载占位图以及错误图

RequestOptions options = new RequestOptions()
    //占位图
    .placeholder(R.drawable.occupancy)
	 //异常图
    .error(R.drawable.error);
	
Glide.with(this)
    .load(IMG_PATH)
    .apply(options)
    .into(imageView);

<2> 指定图片大小

RequestOptions options = new RequestOptions()
    //指定图片的大小
    .override(100, 100);

<3> 指定缓存策略

gilde默认会缓存图片的。

RequestOptions options = new RequestOptions()
    //禁用内存缓存
    .skipMemoryCache(true)
    //禁止缓存
    .diskCacheStrategy(DiskCacheStrategy.NONE);

磁盘缓存策略有以下5种:

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

<4> 指定加载图片资源类型

Glide.with(this)
	.asGif()
    .load(IMG_PATH)
    .into(imageView);

默认情况下glide会自动判断图片的类型进行加载。

除了asGif()还有asBitmap、asFile()、asDrawable()

如果指定了asBitmap,那么加载GIF图片时就会显示成一张静态图。如果指定asGif(),那么加载静态图片时就会加载失败。

<5> 配置过渡动画

Glide.with(context)
    .load(url)
    .transition(DrawableTransitionOptions.withCrossFade(600))//适用于Drawable,过渡动画持续600ms    
    .into(imageView);

	.transition(DrawableTransitionOptions.withCrossFade(600))//适用于Drawable,过渡动画持续600ms   
	.transition(BitmapTransitionOptions.withCrossFade(600))//适用于Bitmap,过渡动画持续600ms
    .transition(GenericTransitionOptions.with(animationId))//适用于自定义过渡效果,传入animationId

<6> 图片变换

Glide内置了几种图片变换操作,比如CenterCrop、FitCenter、CircleCrop等等。

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

除此之外还有一个开源图片转换库glide-transformations

implementation 'jp.wasabeef:glide-transformations:3.0.1'

RequestOptions options = new RequestOptions();
   //加入圆角变换
   options.transform(new RoundedCornersTransformation(radius, margin));
   //加入模糊变换
   //options.transform(new BlurTransformation(blurRadius));
   //加入灰白变换
   //options.transform(new GrayscaleTransformation());
...

另外可以通过dontTransform()禁用图片变换

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

<7> 预加载

如果希望提前对图片进行一个预加载,等真正需要加载图片的时候就直接从缓存中读取。Glide专门提供了预加载的接口,也就是preload()方法。

Glide.with(this)
    .load(IMG_PATH)
    .preload();

调用了预加载之后,想再去加载这张图片就会非常快了,因为Glide会直接从缓存当中去读取图片并显示出来,代码如下所示:

Glide.with(this)
    .load(IMG_PATH)
    .into(imageView);

<8> 回调与监听

into()方法

Glide的into()方法除了可以传入ImageView,也可以传入自定义Target,比如SimpleTarget

SimpleTarget<Drawable> simpleTarget = new SimpleTarget<Drawable>() {
    @Override
    public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
        //可以获取到Drawable对象
    }
};

public void loadImage(View view) {
    Glide.with(this)
        .load(IMG_PATH)
        .into(simpleTarget);

submit()方法

Glide是为了将图片显示到界面上,会对图片进行缓存,但缓存文件是存在哪里以及如何访问缓存文件,并不知道。这就需要用到submit()方法。

这个方法只会下载图片,而不会对图片进行加载。

submit()方法有两个方法重载:

submit()
submit(int width, int height)

当调用了submit()方法后会返回一个FutureTarget对象,然后Glide会在后台开始下载图片文件。

然后调用FutureTarget的get()方法就可以去获取下载好的图片文件了,如果此时图片还没有下载完,那么get()方法就会阻塞住,直到图片下载完成才会有值返回。

由于get()方法会阻塞,所以submit()方法需要在子线程中进行。比如:

new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            final Context context = getApplicationContext();
            FutureTarget<File> target = Glide.with(context)
                    .load(IMG_PATH)
                    .submit();
            final File imageFile = target.get();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(context, imageFile.getPath(), Toast.LENGTH_LONG).show();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}).start();

listener()方法

用来监听Glide加载图片的状态。

Glide.with(this)
    .load(IMG_PATH)
    .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) {
        //加载成功,resource为加载到的Drawable
		return false;
    }
})
.into(imageView);

<9> 自定义模块

自定义模块功能可以更改Glide配置,替换Glide组件.

首先定义一个模块类,并让它继承自AppGlideModule

@GlideModule
public class MyAppGlideModule extends AppGlideModule {

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
    
    }
    
    @Override
    public void registerComponents(Context context, Glide glide, Registry registry) {
    
    }

}

在MyAppGlideModule类当中,重写了applyOptions()和registerComponents()方法,这两个方法分别就是用来更改Glide配置以及替换Glide组件的.

Glide配置

更改Glide的默认配置,只需要在applyOptions()方法中提前将Glide的配置项进行初始化就可以了.

setMemoryCache() 
用于配置Glide的内存缓存策略,默认配置是LruResourceCache。

setBitmapPool() 
用于配置Glide的Bitmap缓存池,默认配置是LruBitmapPool。

setDiskCache() 
用于配置Glide的硬盘缓存策略,默认配置是InternalCacheDiskCacheFactory,默认大小为250m,默认存储到当前应用的私有目录下。

setDiskCacheService() 
用于配置Glide读取缓存中图片的异步执行器,默认配置是FifoPriorityThreadPoolExecutor,也就是先入先出原则。

setResizeService() 
用于配置Glide读取非缓存中图片的异步执行器,默认配置也是FifoPriorityThreadPoolExecutor。

setDecodeFormat() 
用于配置Glide加载图片的解码模式,默认配置是RGB_565。

比如:

@Override
public void applyOptions(Context context, GlideBuilder builder) {
    //更改解码格式设置为ARGB_8888
    builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
	//更改磁盘缓存路径与大小
	int cacheSize100MegaBytes = 500 x 1024 x 1024;
	builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, DISK_CACHE_SIZE));

}

ExternalCacheDiskCacheFactory也是Glide内置的缓存,它是将加载的图片都缓存到SD卡。路径是在sdcard/Android/包名/cache/image_manager_disk_cache目录下。

替换Glide组件

替换Glide组件功能需要在自定义模块的registerComponents()方法中加入具体的替换逻辑。

默认情况下,Glide使用的是基于原生HttpURLConnection进行订制的HTTP通讯组件,可以将其替换成OkHttp。只需要仿照着HttpUrlFetcher和HttpUrlGlideUrlLoader的代码来写就可以了。

除了可以手动实现之外,还有一个开源的glide-okhttp3库。

implementation 'com.github.bumptech.glide:okhttp3-integration:4.8.0'

比如:在上面自定义的MyAppGlideModule中使用。

@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(new HeadInterceptor())
            .build();
    glide.register(GlideUrl.class, InputStream.class, new OkHttpGlideUrlLoader.Factory(okHttpClient));
}

public static class HeadInterceptor implements Interceptor {

    public HeadInterceptor() {
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request.Builder request = chain.request().newBuilder();

        //这里添加我们需要的请求头
        request.addHeader("Referer", "http://www.baidu.com");
        return chain.proceed(request.build());
    }
}

<10> 使用Generated API

使用Generated API,定制出任何属于自己的API.需要借助@GlideExtension和@GlideOption这两个注解.比如:每次在使用Glide加载图片的时候,都去指定diskCacheStrategy(DiskCacheStrategy.DATA),这种情况就需要定制一个自己的API了。

@GlideExtension
public class MyGlideExtension {

    private MyGlideExtension() {

    }

    @GlideOption
    public static void cacheSource(RequestOptions options) {
        options.diskCacheStrategy(DiskCacheStrategy.DATA);
    }

}

GlideApp.with(this)
    .load(IMG_PATH)
    //直接调用cacheSource就可以实现设置diskCacheStrategy方法
    .cacheSource()
    .into(imageView);