添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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: // Do nothing. //(1)方法构建出一个Target对象,然后再把它传入到另一个接收Target参数的into()方法中 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();
    //(1)构建Request
    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()");
        // Recursive case: contains a potentially recursive thumbnail request builder.
        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);
        //(2)Target对象传入到GenericRequest
        Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
        // Guard against infinite recursion.
        isThumbnailBuilt = true;
        // Recursively generate thumbnail requests.
        Request thumbRequest = thumbnailRequestBuilder.buildRequestRecursive(target, coordinator);
        isThumbnailBuilt = false;
        coordinator.setRequests(fullRequest, thumbRequest);
        return coordinator;
    } else if (thumbSizeMultiplier != null) {
        // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
        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 {
        // Base case: no thumbnail.
        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);
            //(3)调用了target.onResourceReady()方法
            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);
            //(1)图片加载完成之后只将它缓存而不去显示它,那不就相当于预加载了
        @Override
        public void onResourceReady(Z resource, GlideAnimation<? super Z> glideAnimation) {
            //(2)Glide.clear()并不是清空缓存的意思,而是表示加载已完成,释放资源的意思,
            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的回调与监听
  • 分类:
    Android
    标签: