public Target<TranscodeType> 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:
return into(glide.buildImageViewTarget(view, transcodeClass));
跟进到glide.buildImageViewTarget()方法中
public class ImageViewTargetFactory {
@SuppressWarnings("unchecked")
public <Z> Target<Z> buildTarget(ImageView view, Class<Z> clazz) {
if (GlideDrawable.class.isAssignableFrom(clazz)) {
return (Target<Z>) new GlideDrawableImageViewTarget(view);
} else if (Bitmap.class.equals(clazz)) {
return (Target<Z>) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (Target<Z>) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException("Unhandled class: " + clazz
+ ", try .as*(Class).transcode(ResourceTranscoder)");
如果你在使用Glide加载图片的时候调用了asBitmap()方法,那么这里就会构建出BitmapImageViewTarget对象,否则的话构建的都是GlideDrawableImageViewTarget对象。至于上述代码中的DrawableImageViewTarget对象,这个通常都是用不到的.
public <Y extends Target<TranscodeType>> Y into(Y target) {
Util.assertMainThread();
if (target == null) {
throw new IllegalArgumentException("You must pass in a non null Target");
if (!isModelSet) {
throw new IllegalArgumentException("You must first set a model (try #load())");
Request previous = target.getRequest();
if (previous != null) {
previous.clear();
requestTracker.removeRequest(previous);
previous.recycle();
Request request = buildRequest(target);
target.setRequest(request);
lifecycle.addListener(target);
requestTracker.runRequest(request);
return target;
private Request buildRequest(Target<TranscodeType> target) {
if (priority == null) {
priority = Priority.NORMAL;
return buildRequestRecursive(target, null);
private Request buildRequestRecursive(Target<TranscodeType> target, ThumbnailRequestCoordinator parentCoordinator) {
if (thumbnailRequestBuilder != null) {
if (isThumbnailBuilt) {
throw new IllegalStateException("You cannot use a request as both the main request and a thumbnail, "
+ "consider using clone() on the request(s) passed to thumbnail()");
if (thumbnailRequestBuilder.animationFactory.equals(NoAnimation.getFactory())) {
thumbnailRequestBuilder.animationFactory = animationFactory;
if (thumbnailRequestBuilder.priority == null) {
thumbnailRequestBuilder.priority = getThumbnailPriority();
if (Util.isValidDimensions(overrideWidth, overrideHeight)
&& !Util.isValidDimensions(thumbnailRequestBuilder.overrideWidth,
thumbnailRequestBuilder.overrideHeight)) {
thumbnailRequestBuilder.override(overrideWidth, overrideHeight);
ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
isThumbnailBuilt = true;
Request thumbRequest = thumbnailRequestBuilder.buildRequestRecursive(target, coordinator);
isThumbnailBuilt = false;
coordinator.setRequests(fullRequest, thumbRequest);
return coordinator;
} else if (thumbSizeMultiplier != null) {
ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
Request thumbnailRequest = obtainRequest(target, thumbSizeMultiplier, getThumbnailPriority(), coordinator);
coordinator.setRequests(fullRequest, thumbnailRequest);
return coordinator;
} else {
return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
Glide在图片加载完成之后又会回调GenericRequest的onResourceReady()方法。
public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallback,
ResourceCallback {
private Target<R> 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<R> animation = animationFactory.build(loadedFromMemoryCache, isFirstResource);
target.onResourceReady(result, animation);
notifyLoadSuccess();
public class GlideDrawableImageViewTarget extends ImageViewTarget<GlideDrawable> {
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {
if (!resource.isAnimated()) {
float viewRatio = view.getWidth() / (float) view.getHeight();
float drawableRatio = resource.getIntrinsicWidth() / (float) resource.getIntrinsicHeight();
if (Math.abs(viewRatio - 1f) <= SQUARE_RATIO_MARGIN
&& Math.abs(drawableRatio - 1f) <= SQUARE_RATIO_MARGIN) {
resource = new SquaringDrawable(resource, view.getWidth());
super.onResourceReady(resource, animation);
this.resource = resource;
resource.setLoopCount(maxLoopCount);
resource.start();
@Override
protected void setResource(GlideDrawable resource) {
view.setImageDrawable(resource);
可以看到,这里在onResourceReady()方法中处理了图片展示,还有GIF播放的逻辑。
构建Target对象。
将Target对象传入GenericRequest。
图片加载成功会回调GenericRequest的onResourceReady。
GenericRequest的onResourceReady里面回调Target的onResourceReady。
Target的onResourceReady会调用view.setImageDrawable(resource)。
into()方法
Glide的into方法可以传入ImageView,也可以传入Target。
SimpleTarget<GlideDrawable> simpleTarget = new SimpleTarget<GlideDrawable>() {
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation glideAnimation) {
imageView.setImageDrawable(resource);
public void loadImage(View view) {
String url = "http://cn.bing.com/az/hprichbg/rb/TOAD_ZH-CN7336795473_1920x1080.jpg";
Glide.with(this)
.load(url)
.into(simpleTarget);
这里为后面的预加载做准备。
preload()方法
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.preload();
public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> implements Cloneable {
public Target<TranscodeType> preload(int width, int height) {
final PreloadTarget<TranscodeType> target = PreloadTarget.obtain(width, height);
return into(target);
public Target<TranscodeType> preload() {
return preload(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
public final class PreloadTarget<Z> extends SimpleTarget<Z> {
public static <Z> PreloadTarget<Z> obtain(int width, int height) {
return new PreloadTarget<Z>(width, height);
private PreloadTarget(int width, int height) {
super(width, height);
@Override
public void onResourceReady(Z resource, GlideAnimation<? super Z> glideAnimation) {
Glide.clear(this);
downloadOnly()方法
downloadOnly(int width, int height)
downloadOnly(Y target)
其中downloadOnly(int width, int height)是用于在子线程中下载图片的,而downloadOnly(Y target)是用于在主线程中下载图片的。
public class DrawableTypeRequest<ModelType> extends DrawableRequestBuilder<ModelType>
implements DownloadOptions {
public FutureTarget<File> downloadOnly(int width, int height) {
return getDownloadOnlyRequest().downloadOnly(width, height);
private GenericTranscodeRequest<ModelType, InputStream, File> getDownloadOnlyRequest() {
return optionsApplier.apply(new GenericTranscodeRequest<ModelType, InputStream, File>(
File.class, this, streamModelLoader, InputStream.class, File.class, optionsApplier));
public class GenericTranscodeRequest<ModelType, DataType, ResourceType>
implements DownloadOptions {
public FutureTarget<File> downloadOnly(int width, int height) {
return getDownloadOnlyRequest().into(width, height);
private GenericRequestBuilder<ModelType, DataType, File, File> getDownloadOnlyRequest() {
ResourceTranscoder<File, File> transcoder = UnitTranscoder.get();
DataLoadProvider<DataType, File> dataLoadProvider = glide.buildDataProvider(dataClass, File.class);
FixedLoadProvider<ModelType, DataType, File, File> fixedLoadProvider =
new FixedLoadProvider<ModelType, DataType, File, File>(modelLoader, transcoder, dataLoadProvider);
return optionsApplier.apply(
new GenericRequestBuilder<ModelType, DataType, File, File>(fixedLoadProvider,
File.class, this))
.priority(Priority.LOW)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.skipMemoryCache(true);
public FutureTarget<TranscodeType> into(int width, int height) {
final RequestFutureTarget<ModelType, TranscodeType> target =
new RequestFutureTarget<ModelType, TranscodeType>(glide.getMainHandler(), width, height);
glide.getMainHandler().post(new Runnable() {
@Override
public void run() {
if (!target.isCancelled()) {
into(target);
return target;
public class RequestFutureTarget<T, R> implements FutureTarget<R>, Runnable {
@Override
public R get() throws InterruptedException, ExecutionException {
try {
return doGet(null);
} catch (TimeoutException e) {
throw new AssertionError(e);
@Override
public R get(long time, TimeUnit timeUnit) throws InterruptedException, ExecutionException,
TimeoutException {
return doGet(timeUnit.toMillis(time));
@Override
public void getSize(SizeReadyCallback cb) {
cb.onSizeReady(width, height);
@Override
public synchronized void onLoadFailed(Exception e, Drawable errorDrawable) {
exceptionReceived = true;
this.exception = e;
waiter.notifyAll(this);
@Override
public synchronized void onResourceReady(R resource, GlideAnimation<? super R> glideAnimation) {
resultReceived = true;
this.resource = resource;
waiter.notifyAll(this);
private synchronized R doGet(Long timeoutMillis) throws ExecutionException, InterruptedException,
TimeoutException {
if (assertBackgroundThread) {
Util.assertBackgroundThread();
if (isCancelled) {
throw new CancellationException();
} else if (exceptionReceived) {
throw new ExecutionException(exception);
} else if (resultReceived) {
return resource;
if (timeoutMillis == null) {
waiter.waitForTimeout(this, 0);
} else if (timeoutMillis > 0) {
waiter.waitForTimeout(this, timeoutMillis);
if (Thread.interrupted()) {
throw new InterruptedException();
} else if (exceptionReceived) {
throw new ExecutionException(exception);
} else if (isCancelled) {
throw new CancellationException();
} else if (!resultReceived) {
throw new TimeoutException();
return resource;
static class Waiter {
public void waitForTimeout(Object toWaitOn, long timeoutMillis) throws InterruptedException {
toWaitOn.wait(timeoutMillis);
public void notifyAll(Object toNotify) {
toNotify.notifyAll();
listener()方法
public void loadImage(View view) {
String url = "http://cn.bing.com/az/hprichbg/rb/TOAD_ZH-CN7336795473_1920x1080.jpg";
Glide.with(this)
.load(url)
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target,
boolean isFirstResource) {
return false;
@Override
public boolean onResourceReady(GlideDrawable resource, String model,
Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
return false;
.into(imageView);
listener()方法是定义在GenericRequestBuilder类当中的,而我们传入到listener()方法中的实例则会赋值到一个requestListener变量当中。
public class GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> implements Cloneable {
private RequestListener<? super ModelType, TranscodeType> requestListener;
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> listener(
RequestListener<? super ModelType, TranscodeType> requestListener) {
this.requestListener = requestListener;
return this;
public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallback,
ResourceCallback {
private RequestListener<? super A, R> requestListener;
private void onResourceReady(Resource<?> resource, R result) {
boolean isFirstResource = isFirstReadyResource();
status = Status.COMPLETE;
this.resource = resource;
(1)返回true就不执行target的onResourceReady
if (requestListener == null || !requestListener.onResourceReady(result, model, target,
loadedFromMemoryCache, isFirstResource)) {
GlideAnimation<R> animation = animationFactory.build(loadedFromMemoryCache, isFirstResource);
target.onResourceReady(result, animation);
notifyLoadSuccess();
public final class GenericRequest<A, T, Z, R> implements Request, SizeReadyCallback,
ResourceCallback {
@Override
public void onException(Exception e) {
status = Status.FAILED;
(1)返回true就不执行占位
if (requestListener == null ||
!requestListener.onException(e, model, target, isFirstReadyResource())) {
setErrorPlaceholder(e);
Android图片加载框架最全解析(四),玩转Glide的回调与监听