Glide 源码分析之三 into

作者: sunrain_ | 来源:发表于2017-05-26 23:02 被阅读390次

    前言

    在前两篇中,我们分析完了 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的执行流程

    相关文章

      网友评论

        本文标题:Glide 源码分析之三 into

        本文链接:https://www.haomeiwen.com/subject/hwqsxxtx.html