Glide源码学习五:回调与监听,总结2021年180道Android岗面试题

Android图片加载框架最全解析(四),玩转Glide的回调与监听

回调的源码实现

=======

作为一名Glide老手,相信大家对于Glide的基本用法已经非常熟练了。我们都知道,使用Glide在界面上加载并展示一张图片只需要一行代码:

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

而在这一行代码的背后,Glide帮我们执行了成千上万行的逻辑。其实在第二篇文章当中,我们已经分析了这一行代码背后的完整执行流程,但是这里我准备再带着大家单独回顾一下回调这部分的源码,这将有助于我们今天这篇文章的学习。

首先来看一下into()方法,这里我们将ImageView的实例传入到into()方法当中,Glide将图片加载完成之后,图片就能显示到ImageView上了。这是怎么实现的呢?我们来看一下into()方法的源码:

public Target into(ImageView view) {

Util.assertMainThread();

if (view == null) {

throw new IllegalArgumentException(“You must pass in a non null View”);

}

if (!isTransformationSet && view.getScaleType() != null) {

switch (view.getScaleType()) {

case CENTER_CROP:

applyCenterCrop();

break;

case FIT_CENTER:

case FIT_START:

case FIT_END:

applyFitCenter();

break;

default:

// Do nothing.

}

}

return into(glide.buildImageViewTarget(view, transcodeClass));

}

可以看到,最后一行代码会调用glide.buildImageViewTarget()方法构建出一个Target对象,然后再把它传入到另一个接收Target参数的into()方法中。Target对象则是用来最终展示图片用的,如果我们跟进到glide.buildImageViewTarget()方法中,你会看到如下的源码:

public class ImageViewTargetFactory {

@SuppressWarnings(“unchecked”)

public Target buildTarget(ImageView view, Class clazz) {

if (GlideDrawable.class.isAssignableFrom(clazz)) {

return (Target) new GlideDrawableImageViewTarget(view);

} else if (Bitmap.class.equals(clazz)) {

return (Target) new BitmapImageViewTarget(view);

} else if (Drawable.class.isAssignableFrom(clazz)) {

return (Target) new DrawableImageViewTarget(view);

} else {

throw new IllegalArgumentException("Unhandled class: " + clazz

  • “, try .as*(Class).transcode(ResourceTranscoder)”);

}

}

}

buildTarget()方法会根据传入的class参数来构建不同的Target对象,如果你在使用Glide加载图片的时候调用了asBitmap()方法,那么这里就会构建出BitmapImageViewTarget对象,否则的话构建的都是GlideDrawableImageViewTarget对象。至于上述代码中的DrawableImageViewTarget对象,这个通常都是用不到的,我们可以暂时不用管它。

之后就会把这里构建出来的Target对象传入到GenericRequest当中,而Glide在图片加载完成之后又会回调GenericRequest的onResourceReady()方法,我们来看一下这部分源码:

public final class GenericRequest implements Request, SizeReadyCallback,

ResourceCallback {

private Target target;

private void onResourceReady(Resource resource, R result) {

boolean isFirstResource = isFirstReadyResource();

status = Status.COMPLETE;

this.resource = resource;

if (requestListener == null || !requestListener.onResourceReady(result, model, target,

loadedFromMemoryCache, isFirstResource)) {

GlideAnimation animation = animationFactory.build(loadedFromMemoryCache, isFirstResource);

target.onResourceReady(result, animation);

}

notifyLoadSuccess();

}

}

这里在第14行调用了target.onResourceReady()方法,而刚才我们已经知道,这里的target就是GlideDrawableImageViewTarget对象,那么我们再来看一下它的源码:

public class GlideDrawableImageViewTarget extends ImageViewTarget {

@Override

public void onResourceReady(GlideDrawable resource, GlideAnimation animation) {

if (!resource.isAnimated()) {

float vie

你可能感兴趣的:(程序员,架构,移动开发,android)