Glide 源码分析之三 into

前言

在前两篇中,我们分析完了 with() 和 load() 方法:
Glide 分析之一 with
Glide 分析之二 load

接下来,我们将通过 load() 方法返回的 DrawableTypeRequest 对象,继续分析 into(imageView) 的过程。

本篇的阅读难度会比前两篇大很多,如果只关心流程,把主线部分看完就可以了,了解更多细节可以继续看支线内容。

为了方便阅读,文章中使用了锚点支线关键字,可以使用浏览器搜索功能进行快速跳转。

into

DrawableTypeRequest 的 into() 方法只是调用了父类 GenericRequestBuilder 的 into() 方法:

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;
            //$CASES-OMITTED$
            default:
                // Do nothing.
        }
    }

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

transform 的逻辑先不分析,只关注最后一行代码。
其中 transcodeClass 为 GlideDrawable.class(见:支线1),glide.buildImageViewTarget() 方法返回了 GlideDrawableImageViewTarget 对象(见:支线2)(锚点1),然后传入 into() 方法中:

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;
}

忽略判断只看主要逻辑,buildRequest() 方法返回了 GenericRequest 对象(见:支线3),之后执行了 requestTracker.runRequest() 方法:

public void runRequest(Request request) {
    requests.add(request);
    if (!isPaused) {
        request.begin();
    } else {
        pendingRequests.add(request);
    }
}

不考虑暂停的情况,直接看 GenericRequest 对象的 begin() 方法:

public void begin() {
    ···
    if (model == null) {
        onException(null);
        return;
    }

    status = GenericRequest.Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {(锚点2)
        onSizeReady(overrideWidth, overrideHeight);
    } else {
        target.getSize(this);
    }

    if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
        target.onLoadStarted(getPlaceholderDrawable());
    }
    ··· 省略log
}

锚点2处,如果之前通过 override(int width, int height) 方法设置过宽高,就会走 onSizeReady() 方法,否则走
target.getSize() 方法。这里的 target 为 GlideDrawableImageViewTarget 对象(见:锚点1),它的 getSize() 方法在父类 ViewTarget 中:

public void getSize(SizeReadyCallback cb) {
    sizeDeterminer.getSize(cb);
}

SizeDeterminer 是 ViewTarget 的内部静态类,它的 getSize() 方法会根据 ImageView 的 layout_width 和 layout_height 计算图片的宽高,获得宽高后会继续调用 onSizeReady() 方法:

public void onSizeReady(int width, int height) {
    ··· 省略log
    if (status != Status.WAITING_FOR_SIZE) {
        return;
    }
    status = Status.RUNNING;

    width = Math.round(sizeMultiplier * width);
    height = Math.round(sizeMultiplier * height);

    ModelLoader<A, T> modelLoader = loadProvider.getModelLoader();
    final DataFetcher<T> dataFetcher = modelLoader.getResourceFetcher(model, width, height);

    if (dataFetcher == null) {
        onException(new Exception("Failed to load model: \'" + model + "\'"));
        return;
    }
    ResourceTranscoder<Z, R> transcoder = loadProvider.getTranscoder();
    ··· 省略log
    loadedFromMemoryCache = true;
    loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
            priority, isMemoryCacheable, diskCacheStrategy, this);
    loadedFromMemoryCache = resource != null;
    ··· 省略log
}

其中:
loadProvider 为 FixedLoadProvider 对象(见:支线4)。
modelLoader 为 ImageVideoModelLoader 对象(见:支线5)。
transcoder 为 GifBitmapWrapperDrawableTranscoder 对象(见:支线5)。
dataFetcher 为 ImageVideoFetcher 对象(见:支线6)(锚点3)。

然后传入 engine.load() 方法中:

public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
                                 DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
                                 Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {
    Util.assertMainThread();
    ···

    final String id = fetcher.getId();
    EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),
            loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),
            transcoder, loadProvider.getSourceEncoder());

    ··· 省略缓存逻辑

    EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
    DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,
            transcoder, diskCacheProvider, diskCacheStrategy, priority);
    EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
    jobs.put(key, engineJob);
    engineJob.addCallback(cb);(锚点4)
    engineJob.start(runnable);
    ···
    return new LoadStatus(cb, engineJob);
}

可以看到创建了一个EngineRunnable 对象,并由 EngineJob 对象执行,看一下 EngineRunnable 的 run() 方法:

public void run() {
    if (isCancelled) {
        return;
    }

    Exception exception = null;
    Resource<?> resource = null;
    try {
        resource = decode();(锚点5)
    } catch (Exception e) {
        ··· 省略log
        exception = e;
    }

    if (isCancelled) {
        if (resource != null) {
            resource.recycle();
        }
        return;
    }

    if (resource == null) {
        onLoadFailed(exception);
    } else {
        onLoadComplete(resource);
    }
}

方法很清晰,主要工作在 decode() 方法中:

private Resource<?> decode() throws Exception {
    if (isDecodingFromCache()) {
        return decodeFromCache();
    } else {
        return decodeFromSource();
    }
}

不考虑缓存的情况,看 decodeFromSource() 方法:

private Resource<?> decodeFromSource() throws Exception {
    return decodeJob.decodeFromSource();
}

这里调用了 DecodeJob 对象的 decodeFromSource() 方法:

public Resource<Z> decodeFromSource() throws Exception {
    Resource<T> decoded = decodeSource();
    return transformEncodeAndTranscode(decoded);
}

private Resource<T> decodeSource() throws Exception {
    Resource<T> decoded = null;
    try {
        ···
        final A data = fetcher.loadData(priority);
        ··· 省略log
        if (isCancelled) {
            return null;
        }
        decoded = decodeFromSourceData(data);
    } finally {
        fetcher.cleanup();
    }
    return decoded;
}

fetcher 为 ImageVideoFetcher 对象(见:锚点3),它的 loadData() 方法:

public ImageVideoWrapper loadData(Priority priority) throws Exception {
    InputStream is = null;
    if (streamFetcher != null) {
        try {
            is = streamFetcher.loadData(priority);
        } catch (Exception e) {
            ··· 省略log
            if (fileDescriptorFetcher == null) {
                throw e;
            }
        }
    }
    ParcelFileDescriptor fileDescriptor = null;
    if (fileDescriptorFetcher != null) {
        try {
            fileDescriptor = fileDescriptorFetcher.loadData(priority);
        } catch (Exception e) {
            ··· 省略log
            if (is == null) {
                throw e;
            }
        }
    }
    return new ImageVideoWrapper(is, fileDescriptor);(锚点6)
}

streamFetcher 就是创建 ImageVideoFetcher 对象时传入的 StreamLocalUriFetcher 对象(见:锚点12),它的 loadData() 方法在父类 LocalUriFetcher 中:

public final T loadData(Priority priority) throws Exception {
    ContentResolver contentResolver = context.getContentResolver();
    data = loadResource(uri, contentResolver);
    return data;
}

loadResource() 方法由子类 StreamLocalUriFetcher 实现:

protected InputStream loadResource(Uri uri, ContentResolver contentResolver) throws FileNotFoundException {
    return contentResolver.openInputStream(uri);
}

现在我们拿到了想要加载文件的输入流,创建 ImageVideoWrapper 对象(见:锚点6),然后传递给 decodeFromSourceData() 方法:

private Resource<T> decodeFromSourceData(A data) throws IOException {
    final Resource<T> decoded;
    ··· 省略缓存
    decoded = loadProvider.getSourceDecoder().decode(data, width, height);
    ···
    return decoded;
}

loadProvider.getSourceDecoder() 返回了 GifBitmapWrapperResourceDecoder 对象(见:支线8),它的 decode() 方法:

public Resource<GifBitmapWrapper> decode(ImageVideoWrapper source, int width, int height) throws IOException {
    ByteArrayPool pool = ByteArrayPool.get();
    byte[] tempBytes = pool.getBytes();

    GifBitmapWrapper wrapper = null;
    try {
        wrapper = decode(source, width, height, tempBytes);
    } finally {
        pool.releaseBytes(tempBytes);
    }
    return wrapper != null ? new GifBitmapWrapperResource(wrapper) : null;
}

private GifBitmapWrapper decode(ImageVideoWrapper source, int width, int height, byte[] bytes) throws IOException {
    final GifBitmapWrapper result;
    if (source.getStream() != null) {
        result = decodeStream(source, width, height, bytes);
    } else {
        result = decodeBitmapWrapper(source, width, height);
    }
    return result;
}

private GifBitmapWrapper decodeStream(ImageVideoWrapper source, int width, int height, byte[] bytes)
        throws IOException {
    InputStream bis = streamFactory.build(source.getStream(), bytes);
    bis.mark(MARK_LIMIT_BYTES);
    ImageHeaderParser.ImageType type = parser.parse(bis);
    bis.reset();

    GifBitmapWrapper result = null;
    if (type == ImageHeaderParser.ImageType.GIF) {
        result = decodeGifWrapper(bis, width, height);
    }
    // Decoding the gif may fail even if the type matches.
    if (result == null) {
        ImageVideoWrapper forBitmapDecoder = new ImageVideoWrapper(bis, source.getFileDescriptor());
        result = decodeBitmapWrapper(forBitmapDecoder, width, height);
    }
    return result;
}

private GifBitmapWrapper decodeBitmapWrapper(ImageVideoWrapper toDecode, int width, int height) throws IOException {
    GifBitmapWrapper result = null;

    Resource<Bitmap> bitmapResource = bitmapDecoder.decode(toDecode, width, height);
    if (bitmapResource != null) {
        result = new GifBitmapWrapper(bitmapResource, null);
    }

    return result;
}

在 decodeBitmapWrapper() 方法中,bitmapDecoder 为 ImageVideoBitmapDecoder 对象(见:支线9),它的 decode() 方法:

public Resource<Bitmap> decode(ImageVideoWrapper source, int width, int height) throws IOException {
    Resource<Bitmap> result = null;
    InputStream is = source.getStream();
    if (is != null) {
        try {
            result = streamDecoder.decode(is, width, height);
        } catch (IOException e) {
            ··· 省略log
        }
    }

    if (result == null) {
        ParcelFileDescriptor fileDescriptor = source.getFileDescriptor();
        if (fileDescriptor != null) {
            result = fileDescriptorDecoder.decode(fileDescriptor, width, height);
        }
    }
    return result;
}

因为我们之前传入了 InputStream,所以会执行 streamDecoder.decode() 方法,streamDecoder 为 StreamBitmapDecoder对象(见:支线12),它的 decode() 方法:

public Resource<Bitmap> decode(InputStream source, int width, int height) {
    Bitmap bitmap = downsampler.decode(source, bitmapPool, width, height, decodeFormat);
    return BitmapResource.obtain(bitmap, bitmapPool);
}

继续看 downsampler.decode() 方法:

public Bitmap decode(InputStream is, BitmapPool pool, int outWidth, int outHeight, DecodeFormat decodeFormat) {
    final ByteArrayPool byteArrayPool = ByteArrayPool.get();
    final byte[] bytesForOptions = byteArrayPool.getBytes();
    final byte[] bytesForStream = byteArrayPool.getBytes();
    final BitmapFactory.Options options = getDefaultOptions();

    RecyclableBufferedInputStream bufferedStream = new RecyclableBufferedInputStream(
            is, bytesForStream);
    ExceptionCatchingInputStream exceptionStream =
            ExceptionCatchingInputStream.obtain(bufferedStream);
    MarkEnforcingInputStream invalidatingStream = new MarkEnforcingInputStream(exceptionStream);
    try {
        exceptionStream.mark(MARK_POSITION);
        int orientation = 0;
        try {
            orientation = new ImageHeaderParser(exceptionStream).getOrientation();
        } catch (IOException e) {
           
        } finally {
            try {
                exceptionStream.reset();
            } catch (IOException e) {
               
            }
        }

        options.inTempStorage = bytesForOptions;

        final int[] inDimens = getDimensions(invalidatingStream, bufferedStream, options);
        final int inWidth = inDimens[0];
        final int inHeight = inDimens[1];

        final int degreesToRotate = TransformationUtils.getExifOrientationDegrees(orientation);
        final int sampleSize = getRoundedSampleSize(degreesToRotate, inWidth, inHeight, outWidth, outHeight);

        final Bitmap downsampled =
                downsampleWithSize(invalidatingStream, bufferedStream, options, pool, inWidth, inHeight, sampleSize,
                        decodeFormat);

        final Exception streamException = exceptionStream.getException();
        if (streamException != null) {
            throw new RuntimeException(streamException);
        }

        Bitmap rotated = null;
        if (downsampled != null) {
            rotated = TransformationUtils.rotateImageExif(downsampled, pool, orientation);

            if (!downsampled.equals(rotated) && !pool.put(downsampled)) {
                downsampled.recycle();
            }
        }

        return rotated;
    } finally {
        byteArrayPool.releaseBytes(bytesForOptions);
        byteArrayPool.releaseBytes(bytesForStream);
        exceptionStream.release();
        releaseOptions(options);
    }
}

看到 BitmapFactory.Options 变量和 sampleSize 变量就知道,本篇分析想要找的问题,终于在这里得到了答案。
其中详细的处理过程都大同小异,不再赘述。
这个方法最终返回了 Bitmap 对象。

至此图片解析的过程就结束了,接下来的流程就是传递 Bitmap 到上层传递并最终加载到 ImageView 中。

BitmapResource.obtain() 方法将 Bitmap 对象包装成 BitmapResource 对象,返回给 ImageVideoBitmapDecoder,然后继续返回到 GifBitmapWrapperResourceDecoder 的 decodeStream() 方法中,包装为 GifBitmapWrapper 对象,返回给 DecodeJob 对象的 decodeFromSource() 方法接下来会调用 transformEncodeAndTranscode() 方法:

private Resource<Z> transformEncodeAndTranscode(Resource<T> decoded) {
    Resource<T> transformed = transform(decoded);
    ···
    Resource<Z> result = transcode(transformed);
    return result;
}

transform() 方法将传入的参数原样返回(见:支线14),然后传递给 transcode() 方法:

private Resource<Z> transcode(Resource<T> transformed) {
    if (transformed == null) {
        return null;
    }
    return transcoder.transcode(transformed);
}

transcoder 为 GifBitmapWrapperDrawableTranscoder 对象(见:锚点9),它的 transcode() 方法:

public Resource<GlideDrawable> transcode(Resource<GifBitmapWrapper> toTranscode) {
    GifBitmapWrapper gifBitmap = toTranscode.get();
    Resource<Bitmap> bitmapResource = gifBitmap.getBitmapResource();

    final Resource<? extends GlideDrawable> result;
    if (bitmapResource != null) {
        result = bitmapDrawableResourceTranscoder.transcode(bitmapResource);
    } else {
        result = gifBitmap.getGifResource();
    }
    // This is unchecked but always safe, anything that extends a Drawable can be safely cast to a Drawable.
    return (Resource<GlideDrawable>) result;
}

其中 bitmapDrawableResourceTranscoder 为 GlideBitmapDrawableTranscoder 对象(见:锚点10),看它的 transcode() 方法:

public Resource<GlideBitmapDrawable> transcode(Resource<Bitmap> toTranscode) {
    GlideBitmapDrawable drawable = new GlideBitmapDrawable(resources, toTranscode.get());
    return new GlideBitmapDrawableResource(drawable, bitmapPool);
}

返回了 GlideBitmapDrawableResource 对象,它实现了 Resource<GlideBitmapDrawable> 接口。

最终返回到 EngineRunnable 的 run() 方法处(见:锚点5),之后执行 onLoadComplete() 方法:

private void onLoadComplete(Resource resource) {
    manager.onResourceReady(resource);
}

manager 为 EngineRunnable 创建时传入的 EngineJob 对象,它的 onResourceReady() 方法:

public void onResourceReady(final Resource<?> resource) {
    this.resource = resource;
    MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
}

MAIN_THREAD_HANDLER 的 Callback 实现:

private static final Handler MAIN_THREAD_HANDLER = new Handler(Looper.getMainLooper(), new MainThreadCallback());

private static class MainThreadCallback implements Handler.Callback {
    @Override
    public boolean handleMessage(Message message) {
        if (MSG_COMPLETE == message.what || MSG_EXCEPTION == message.what) {
            EngineJob job = (EngineJob) message.obj;
            if (MSG_COMPLETE == message.what) {
                job.handleResultOnMainThread();
            } else {
                job.handleExceptionOnMainThread();
            }
            return true;
        }
        return false;
    }
}

这里执行了 job.handleResultOnMainThread() 方法:

private void handleResultOnMainThread() {
    if (isCancelled) {
        resource.recycle();
        return;
    } else if (cbs.isEmpty()) {
        throw new IllegalStateException("Received a resource without any callbacks to notify");
    }
    engineResource = engineResourceFactory.build(resource, isCacheable);
    hasResource = true;

    engineResource.acquire();
    listener.onEngineJobComplete(key, engineResource);

    for (ResourceCallback cb : cbs) {
        if (!isInIgnoredCallbacks(cb)) {
            engineResource.acquire();
            cb.onResourceReady(engineResource);
        }
    }
    // Our request is complete, so we can release the resource.
    engineResource.release();
}

通过 engineResourceFactory.build() 方法将 resource 封装进 EngineResource 对象,然后调用了 ResourceCallback 的 onResourceReady() 方法传递出去。

GenericRequest 实现了 ResourceCallback 接口(见:支线15),看它的 onResourceReady() 方法:

public void onResourceReady(Resource<?> resource) {
    ··· 省略检查参数合法性的步骤
    Object received = resource.get();
    ··· 省略检查参数合法性的步骤

    if (!canSetResource()) {
        releaseResource(resource);
        // We can't set the status to complete before asking canSetResource().
        status = GenericRequest.Status.COMPLETE;
        return;
    }

    onResourceReady(resource, (R) received);
}

private void onResourceReady(Resource<?> resource, R result) {
    // We must call isFirstReadyResource before setting status.
    boolean isFirstResource = isFirstReadyResource();
    status = GenericRequest.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();
    ··· 省略log
}

创建了一个动画和 result 作为参数 target.onResourceReady() 方法。
target 为 glide.buildImageViewTarget() 方法创建的 GlideDrawableImageViewTarget 对象(见:锚点1),
看它的 onResourceReady() 方法:

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();
}

这里又调用了父类的 onResourceReady() 方法:

public void onResourceReady(Z resource, GlideAnimation<? super Z> glideAnimation) {
    if (glideAnimation == null || !glideAnimation.animate(resource, this)) {
        setResource(resource);
    }
}

其中,glideAnimation.animate() 方法执行了图片第一次显示时的淡入动画。
setResource() 方法由子类实现:

protected void setResource(GlideDrawable resource) {
    view.setImageDrawable(resource);
}

这个 view 就是 into() 方法中传入的 ImageView .
至此,图片终于显示出来了。
通过Glide.with(this).load(resourceId).into(imageView)这行代码,对 Glide 执行流程的分析到此也就结束了。
谢谢大家。


支线1:transcodeClass 是什么

transcodeClass 在 GenericRequestBuilder 中是 final 修饰的成员变量,在 GenericRequestBuilder 构造函数中初始化,在第二篇 load() 方法创建 DrawableTypeRequest 对象时传入,看一下 DrawableTypeRequest 的构造方法:

DrawableTypeRequest(Class<ModelType> modelClass, ModelLoader<ModelType, InputStream> streamModelLoader,
                    ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader, Context context, Glide glide,
                    RequestTracker requestTracker, Lifecycle lifecycle, RequestManager.OptionsApplier optionsApplier) {
    super(context, modelClass,
          buildProvider(glide, streamModelLoader, fileDescriptorModelLoader, 
                        GifBitmapWrapper.class, GlideDrawable.class, null),
          glide, requestTracker, lifecycle);
    this.streamModelLoader = streamModelLoader;
    this.fileDescriptorModelLoader = fileDescriptorModelLoader;
    this.optionsApplier = optionsApplier;
}

继续看到它调用的父类构造方法:

DrawableRequestBuilder(Context context, Class<ModelType> modelClass,
                       LoadProvider<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable> loadProvider, Glide glide,
                       RequestTracker requestTracker, Lifecycle lifecycle) {
    super(context, modelClass, loadProvider, GlideDrawable.class, glide, requestTracker, lifecycle);
    // Default to animating.
    crossFade();
}

注意 GlideDrawable.class,这就是传递给父类 GenericRequestBuilder 中 transcodeClass 参数的值(锚点7)。

支线2:buildImageViewTarget() 方法返回值

<R> Target<R> buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) {
    return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
}

跟进看buildTarget()方法:

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)");
    }
}

transcodedClass 为 GlideDrawable.class(见:锚点7),所以返回了 GlideDrawableImageViewTarget 对象。

支线3:buildRequest(target) 方法返回值

Request 是一个接口,来看看 buildRequest() 方法返回了哪个实现类:

private Request buildRequest(Target<TranscodeType> target) {
    ···
    return buildRequestRecursive(target, null);
}

private Request buildRequestRecursive(Target<TranscodeType> target, ThumbnailRequestCoordinator parentCoordinator) {
    if (thumbnailRequestBuilder != null) {
       ··· 忽略略缩图逻辑
    } else if (thumbSizeMultiplier != null) {
       ··· 忽略略缩图逻辑
    } else {
        // Base case: no thumbnail.
        return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
    }
}

private Request obtainRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
                              RequestCoordinator requestCoordinator) {
    return GenericRequest.obtain(
            loadProvider,
            model,
            signature,
            context,
            priority,
            target,
            sizeMultiplier,
            placeholderDrawable,
            placeholderId,
            errorPlaceholder,
            errorId,
            fallbackDrawable,
            fallbackResource,
            requestListener,
            requestCoordinator,
            glide.getEngine(),
            transformation,
            transcodeClass,
            isCacheable,
            animationFactory,
            overrideWidth,
            overrideHeight,
            diskCacheStrategy);
}

GenericRequest.obtain() 方法创建了 GenericRequest 对象,所以 buildRequest() 方法最终返回了 GenericRequest 对象。

支线4:loadProvider 是什么

loadProvider 在 DrawableTypeRequest 的构造方法创建:

DrawableTypeRequest(Class<ModelType> modelClass, ModelLoader<ModelType, InputStream> streamModelLoader,
                    ModelLoader<ModelType, ParcelFileDescriptor> fileDescriptorModelLoader, Context context, Glide glide,
                    RequestTracker requestTracker, Lifecycle lifecycle, RequestManager.OptionsApplier optionsApplier) {
    super(context, modelClass,
          buildProvider(glide, streamModelLoader, fileDescriptorModelLoader, 
                        GifBitmapWrapper.class, GlideDrawable.class, null),
          glide, requestTracker, lifecycle);
    this.streamModelLoader = streamModelLoader;
    this.fileDescriptorModelLoader = fileDescriptorModelLoader;
    this.optionsApplier = optionsApplier;
}

DrawableTypeRequest 通过 buildProvider() 方法创建了 FixedLoadProvider 对象:

private static <A, Z, R> FixedLoadProvider<A, ImageVideoWrapper, Z, R> buildProvider(Glide glide,
            ModelLoader<A, InputStream> streamModelLoader,
            ModelLoader<A, ParcelFileDescriptor> fileDescriptorModelLoader, Class<Z> resourceClass,
            Class<R> transcodedClass, ResourceTranscoder<Z, R> transcoder) {
    ···
    return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
}

所以 loadProvider 就是 FixedLoadProvider 对象。

支线5:创建 FixedLoadProvider 对象时的三个参数是什么

private static <A, Z, R> FixedLoadProvider<A, ImageVideoWrapper, Z, R> buildProvider(Glide glide,
            ModelLoader<A, InputStream> streamModelLoader,
            ModelLoader<A, ParcelFileDescriptor> fileDescriptorModelLoader, Class<Z> resourceClass,
            Class<R> transcodedClass, ResourceTranscoder<Z, R> transcoder) {
    ···
    if (transcoder == null) {
        transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
    }
    DataLoadProvider<ImageVideoWrapper, Z> dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class,
            resourceClass);
    ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,
            fileDescriptorModelLoader);
    return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
}

可以看到 modelLoader 是 ImageVideoModelLoader 对象,而创建时放入的 streamModelLoader 是 StreamResourceLoader 对象(锚点8),fileDescriptorModelLoader 是 FileDescriptorResourceLoader 对象(第二篇最后分析过)。

transcoder 来自 glide.buildTranscoder() 方法:

<Z, R> ResourceTranscoder<Z, R> buildTranscoder(Class<Z> decodedClass, Class<R> transcodedClass) {
    return transcoderRegistry.get(decodedClass, transcodedClass);
}

decodedClass 在 DrawableTypeRequest 构造方法中传递过来,值为 GifBitmapWrapper.class.
transcodedClass 就是上边分析过的 GlideDrawable.class(见:锚点7)。

transcoderRegistry 在 Glide 的构造方法中放入数据:

transcoderRegistry.register(
  GifBitmapWrapper.class, 
  GlideDrawable.class, 
  new GifBitmapWrapperDrawableTranscoder(new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));

所以 transcoder 就是 buildTranscoder() 方法返回的 GifBitmapWrapperDrawableTranscoder 对象(锚点9)。
创建 GifBitmapWrapperDrawableTranscoder 对象时,放入了 GlideBitmapDrawableTranscoder 对象(锚点10)。

glide.buildDataProvider() 方法同理,它返回了 ImageVideoGifDrawableLoadProvider 对象(锚点11)。

所以传入 FixedLoadProvider 构造方法的三个参数分别为:ImageVideoModelLoader 对象,GifBitmapWrapperDrawableTranscoder 对象,ImageVideoGifDrawableLoadProvider 对象。

支线6 modelLoader.getResourceFetcher() 方法返回值

public DataFetcher<ImageVideoWrapper> getResourceFetcher(A model, int width, int height) {
    DataFetcher<InputStream> streamFetcher = null;
    if (streamLoader != null) {
        streamFetcher = streamLoader.getResourceFetcher(model, width, height);
    }
    DataFetcher<ParcelFileDescriptor> fileDescriptorFetcher = null;
    if (fileDescriptorLoader != null) {
        fileDescriptorFetcher = fileDescriptorLoader.getResourceFetcher(model, width, height);
    }

    if (streamFetcher != null || fileDescriptorFetcher != null) {
        return new ImageVideoFetcher(streamFetcher, fileDescriptorFetcher);
    } else {
        return null;
    }
}

其中 streamLoader 为 StreamResourceLoader(见:锚点8),它的 getResourceFetcher() 方法在父类 ResourceLoader 中:

public DataFetcher<T> getResourceFetcher(Integer model, int width, int height) {
    Uri uri = null;
    try {
        uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
                + resources.getResourcePackageName(model) + '/'
                + resources.getResourceTypeName(model) + '/'
                + resources.getResourceEntryName(model));
    } catch (Resources.NotFoundException e) {
        ··· 省略log
    }

    if (uri != null) {
        return uriLoader.getResourceFetcher(uri, width, height);
    } else {
        return null;
    }
}

uriLoader 为 StreamUriLoader 对象(见:支线7),它的 getResourceFetcher 方法在父类 UriLoader 中:

public final DataFetcher<T> getResourceFetcher(Uri model, int width, int height) {
    final String scheme = model.getScheme();

    DataFetcher<T> result = null;
    if (isLocalUri(scheme)) {
        if (AssetUriParser.isAssetUri(model)) {
            String path = AssetUriParser.toAssetPath(model);
            result = getAssetPathFetcher(context, path);
        } else {
            result = getLocalUriFetcher(context, model);
        }
    } else if (urlLoader != null && ("http".equals(scheme) || "https".equals(scheme))) {
        result = urlLoader.getResourceFetcher(new GlideUrl(model.toString()), width, height);
    }

    return result;
}

private static boolean isLocalUri(String scheme) {
    return ContentResolver.SCHEME_FILE.equals(scheme)
            || ContentResolver.SCHEME_CONTENT.equals(scheme)
            || ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme);
}
public static boolean isAssetUri(Uri uri) {
    return ContentResolver.SCHEME_FILE.equals(uri.getScheme()) && !uri.getPathSegments().isEmpty()
            && ASSET_PATH_SEGMENT.equals(uri.getPathSegments().get(0));
}

通过这两个方法的判断,最终会执行子类 StreamUriLoader 实现的 getLocalUriFetcher() 方法:

protected DataFetcher<InputStream> getLocalUriFetcher(Context context, Uri uri) {
    return new StreamLocalUriFetcher(context, uri);
}

所以 streamLoader.getResourceFetcher() 返回了 StreamLocalUriFetcher 对象。
而 loadProvider 为之前传入的 FileDescriptorResourceLoader 对象,它的 getResourceFetcher() 方法同理,返回了 FileDescriptorLocalUriFetcher 对象。

最终创建 ImageVideoFetcher 对象并传入 StreamLocalUriFetcher对象(锚点12)和 FileDescriptorLocalUriFetcher 对象,最后返回。

支线7 uriLoader 是什么

uriLoader 为在 StreamResourceLoader 的父类 ResourceLoader 的构造方法中传入,查找 StreamResourceLoader 创建时传入的 uriLoader:

public ModelLoader<Integer, InputStream> build(Context context, GenericLoaderFactory factories) {
    return new StreamResourceLoader(context, factories.buildModelLoader(Uri.class, InputStream.class));
}

查看 factories.buildModelLoader() 方法:

public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
    ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
    ···
    final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
    if (factory != null) {
        result = factory.build(context, this);
        ···
    } else {
        ···
    }
    return result;
}

又是出场很多次的 getFactory() 方法,直接在 Glide 构造方法中找到对应的 Factory 为 StreamUriLoader.Factory(),所以 uriLoader 为 StreamUriLoader 对象。

支线8:loadProvider.getSourceDecoder() 返回值

loadProvider 为 FixedLoadProvider 对象,它的 getSourceDecoder() 方法:

public ResourceDecoder<T, Z> getSourceDecoder() {
    return dataLoadProvider.getSourceDecoder();
}

dataLoadProvider 为 ImageVideoGifDrawableLoadProvider 对象(见:锚点11),它的 sourceDecoder 为
GifBitmapWrapperResourceDecoder 对象:

public ImageVideoGifDrawableLoadProvider(DataLoadProvider<ImageVideoWrapper, Bitmap> bitmapProvider,
                                         DataLoadProvider<InputStream, GifDrawable> gifProvider, BitmapPool bitmapPool) {

    final GifBitmapWrapperResourceDecoder decoder = new GifBitmapWrapperResourceDecoder(
            bitmapProvider.getSourceDecoder(),
            gifProvider.getSourceDecoder(),
            bitmapPool
    );
    ···
    sourceDecoder = decoder;
    ···
}

所以返回了GifBitmapWrapperResourceDecoder 对象。

支线9:bitmapDecoder 是什么

bitmapDecoder 在 GifBitmapWrapperResourceDecoder 创建时传入:

public GifBitmapWrapperResourceDecoder(ResourceDecoder<ImageVideoWrapper, Bitmap> bitmapDecoder,
                                       ResourceDecoder<InputStream, GifDrawable> gifDecoder, BitmapPool bitmapPool) {
    this(bitmapDecoder, gifDecoder, bitmapPool, DEFAULT_PARSER, DEFAULT_STREAM_FACTORY);
}

GifBitmapWrapperResourceDecoder 对象在 ImageVideoGifDrawableLoadProvider 的构造方法中创建:

public ImageVideoGifDrawableLoadProvider(DataLoadProvider<ImageVideoWrapper, Bitmap> bitmapProvider,
                                         DataLoadProvider<InputStream, GifDrawable> gifProvider, BitmapPool bitmapPool) {

    final GifBitmapWrapperResourceDecoder decoder = new GifBitmapWrapperResourceDecoder(
            bitmapProvider.getSourceDecoder(),
            gifProvider.getSourceDecoder(),
            bitmapPool
    );
    ···
}

bitmapProvider 为 ImageVideoDataLoadProvider 对象(见:支线10),它的 getSourceDecoder() 方法返回了 ImageVideoBitmapDecoder 对象(见:支线11)。
所以 bitmapDecoder 就是 ImageVideoBitmapDecoder 对象。

支线10:bitmapProvider 是什么

bitmapProvider 在 ImageVideoGifDrawableLoadProvider 的构造方法中传入,ImageVideoGifDrawableLoadProvider 对象在 Glide 构造方法中创建:

dataLoadProviderRegistry.register(ImageVideoWrapper.class, GifBitmapWrapper.class,
                new ImageVideoGifDrawableLoadProvider(imageVideoDataLoadProvider, gifDrawableLoadProvider, bitmapPool));

创建时使用的 imageVideoDataLoadProvider 对象也在 Glide 构造方法中创建:

ImageVideoDataLoadProvider imageVideoDataLoadProvider =
                new ImageVideoDataLoadProvider(streamBitmapLoadProvider, fileDescriptorLoadProvider);

bitmapProvider 就是 ImageVideoDataLoadProvider 对象。

支线11:getSourceDecoder()方法返回值

getSourceDecoder() 方法直接返回了在构造方法中创建的成员变量 sourceDecoder:

public ImageVideoDataLoadProvider(DataLoadProvider<InputStream, Bitmap> streamBitmapProvider,
                                  DataLoadProvider<ParcelFileDescriptor, Bitmap> fileDescriptorBitmapProvider) {
    sourceDecoder = new ImageVideoBitmapDecoder(streamBitmapProvider.getSourceDecoder(),
            fileDescriptorBitmapProvider.getSourceDecoder());
}

所以 getSourceDecoder() 方法返回了 ImageVideoBitmapDecoder 对象。

支线12:streamDecoder 是什么

streamDecoder 在 ImageVideoBitmapDecoder 的构造方法中传入,ImageVideoBitmapDecoder 对象在
ImageVideoDataLoadProvider 构造方法中创建:

public ImageVideoDataLoadProvider(DataLoadProvider<InputStream, Bitmap> streamBitmapProvider,
                                  DataLoadProvider<ParcelFileDescriptor, Bitmap> fileDescriptorBitmapProvider) {
    sourceDecoder = new ImageVideoBitmapDecoder(streamBitmapProvider.getSourceDecoder(),
            fileDescriptorBitmapProvider.getSourceDecoder());
}

streamBitmapProvider 为 StreamBitmapDataLoadProvider 对象(见:支线13),它的 getSourceDecoder()
方法直接返回了在构造方法中创建的成员变量 decoder:

public StreamBitmapDataLoadProvider(BitmapPool bitmapPool, DecodeFormat decodeFormat) {
    ···
    decoder = new StreamBitmapDecoder(bitmapPool, decodeFormat);
    ···
}

所以 streamDecoder 就是 StreamBitmapDecoder 对象。

支线13:streamBitmapProvider 是什么

streamBitmapProvider 在 ImageVideoDataLoadProvider 构造方法中传入,ImageVideoDataLoadProvider 对象和创建时使用的 streamBitmapLoadProvider 在 Glide 构造方法中创建:

ImageVideoDataLoadProvider imageVideoDataLoadProvider =
                new ImageVideoDataLoadProvider(streamBitmapLoadProvider, fileDescriptorLoadProvider);

StreamBitmapDataLoadProvider streamBitmapLoadProvider =
                new StreamBitmapDataLoadProvider(bitmapPool, decodeFormat);

所以 streamBitmapProvider 为 StreamBitmapDataLoadProvider 对象。

StreamBitmapDataLoadProvider 对象创建时传入了 bitmapPool,decodeFormat 参数。
这两个参数从 Glide 构造方法中传入,bitmapPool 如果没有设置过并且 Build.VERSION.SDK_INT 大于11,默认为 LruBitmapPool,decodeFormat 如果没有通过 API 设置过默认为 PREFER_RGB_565。

支线14:transform() 方法如何将传入的参数原样返回

private Resource<T> transform(Resource<T> decoded) {
    if (decoded == null) {
        return null;
    }

    Resource<T> transformed = transformation.transform(decoded, width, height);
    if (!decoded.equals(transformed)) {
        decoded.recycle();
    }
    return transformed;
}

transformation 来自于 GenericRequestBuilder 的成员变量:

private Transformation<ResourceType> transformation = UnitTransformation.get();

UnitTransformation.get() 方法获取了一个 UnitTransformation 对象,它的 transform() 方法直接返回了传递进来的参数:

public Resource<T> transform(Resource<T> resource, int outWidth, int outHeight) {
    return resource;
}

支线15:谁实现了 ResourceCallback

ResourceCallback 在 EngineJob 的 addCallback() 方法中添加,engine 对象执行 load() 方法时会调用
engineJob.addCallback() 方法(见:锚点4)。
GenericRequest 中实现了 ResourceCallback 接口并在调用 engine.load() 方法时传递了 this 进去。
所以这里的 ResourceCallback 实现类就是 GenericRequest.

参考链接

Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容