Glide2:into方法详解

4. into()方法,最重要 最核心的方法。

实际的加载请求,

// 1.
Glide.with(getApplicationContext()).load(url).into(imageView);
    ↓
public Target<GlideDrawable> into(ImageView view) {
    return super.into(view); //2.调用父类方法
}
    ↓
//3. GenericRequestBuilder.java
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(); //3.1 按比例扩大,居中显示
                break;
            case FIT_CENTER:
            case FIT_START:
            case FIT_END:
                applyFitCenter();
                break;
            default:  // Do nothing.
        }
    }
    // 4.
    return into(glide.buildImageViewTarget(view, transcodeClass));
}
    ↓
//3.1 DrawableRequestBuilder.java
void applyCenterCrop() {
    centerCrop();
}
    ↓
// 3.2
public DrawableRequestBuilder<ModelType> centerCrop() {
    return transform(glide.getDrawableCenterCrop());
}
// 3.3
public DrawableRequestBuilder<ModelType> transform(Transformation<GifBitmapWrapper>... transformation) {
    super.transform(transformation);
    return this;
}
// 3.4 GenericRequestBuilder.java
    public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> transform(
            Transformation<ResourceType>... transformations) {
        isTransformationSet = true; //初始化操作 赋值
        if (transformations.length == 1) {
            transformation = transformations[0];
        } else {
            transformation = new MultiTransformation<ResourceType>(transformations);
        }
        return this;
    }    

接上面,第四步骤 创建好Target

// 4.0
return into(glide.buildImageViewTarget(view, transcodeClass));
// public interface Target<R> extends LifecycleListener 
// 4.1 封装成Target,通过工厂构建。
<R> Target<R> buildImageViewTarget(ImageView imageView, Class<R> transcodedClass) {
        return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
}
// 4.2 通过clazz,判断到底加载那种图片,就创建对应的Target。
public class ImageViewTargetFactory {
    @SuppressWarnings("unchecked")
    public <Z> Target<Z> buildTarget(ImageView view, Class<Z> clazz) {
        if (GlideDrawable.class.isAssignableFrom(clazz)) {//默认的返回 GlideDrawableImageViewTarget
            return (Target<Z>) new GlideDrawableImageViewTarget(view);
        } else if (Bitmap.class.equals(clazz)) { //已调用asBitmap,返回BitmapImageViewTarget
            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)");
        }
    }
}

//Target 实现类有 ImageViewTarget 用于显示图片。
// 内有抽象方法 protected abstract void setResource(Z resource);
// BitmapImageViewTarget:
@Override
protected void setResource(Bitmap resource) {
    view.setImageBitmap(resource);
}
//当Activity销毁,控制图片不继续加载。
public interface LifecycleListener { //接口定义3个生命周期方法
    void onStart();
    void onStop();
    void onDestroy();
}
//-------------------------------------------

上面构建好了Target,传入给into方法。

public <Y extends Target<TranscodeType>> Y into(Y target) {
    Util.assertMainThread(); // 5.0 主线程判断
    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())");
    }
    //5.1 获取当前target 绑定的request,先删除旧的,再绑定新的request到target中。
    Request previous = target.getRequest();
    if (previous != null) {
        previous.clear();
        requestTracker.removeRequest(previous);//暂停request,避免图片错位。
        previous.recycle(); //成员变量清空
        //REQUEST_POOL.offer(this); //放到请求池中,以供复用
    }
    
    //5.2 创建新的request,imageView与 request请求绑定。
    Request request = buildRequest(target);
    target.setRequest(request); //绑定setTag,target绑定request,防止列表中图片错位
    lifecycle.addListener(target);//设置监听事件
    requestTracker.runRequest(request);//【重要】6.
    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) {
        
    } 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);
    }
    
obtain() {
    //从复用池中获取
    GenericRequest<A, T, Z, R> request = (GenericRequest<A, T, Z, R>) REQUEST_POOL.poll();
    request.init(); //初始化操作
    return request;
}

6. requestTracker.runRequest(request);

// 6.0
public void runRequest(Request request) {
    requests.add(request); //加入到set集合中
    if (!isPaused) {
        request.begin(); //6.1开始一个异步请求
    } else {
        pendingRequests.add(request); //一组尚未完成且已排队等待再次运行的请求。
    }
}
// 6.1
@Override
public void begin() {
    startTime = LogTime.getLogTime();
    if (model == null) {
        onException(null);
        return;
    }
    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {//是否调用override方法。
        onSizeReady(overrideWidth, overrideHeight); //****不要再计算****
    } else { //未指定图片宽高, 6.2重新计算宽高,进行view的测量
        target.getSize(this);
    }

    if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
        //开始加载,设定占位符
        target.onLoadStarted(getPlaceholderDrawable());
    }
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        logV("finished run method in " + LogTime.getElapsedMillis(startTime));
    }
}
//6.2 ViewTarget
public void getSize(SizeReadyCallback cb) {
    sizeDeterminer.getSize(cb);
}
//6.3 ViewTarget,计算应该展示的宽高值。
public void getSize(SizeReadyCallback cb) {
    int currentWidth = getViewWidthOrParam(); //获取宽高
    int currentHeight = getViewHeightOrParam();
    if (isSizeValid(currentWidth) && isSizeValid(currentHeight)) {
        cb.onSizeReady(currentWidth, currentHeight);//重点方法 6.4, 回调执行onSizeReady.
    } else {
        // We want to notify callbacks in the order they were added and we only expect one or two callbacks to
        // be added a time, so a List is a reasonable choice.
        if (!cbs.contains(cb)) {
            cbs.add(cb);
        }
        if (layoutListener == null) { 
            final ViewTreeObserver observer = view.getViewTreeObserver();
            layoutListener = new SizeDeterminerLayoutListener(this);
            observer.addOnPreDrawListener(layoutListener);//测量完毕
        }
    }
}
// 6.4 GenericRequest.java 【重点方法】
@Override
public void onSizeReady(int width, int height) {
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
    }
    if (status != Status.WAITING_FOR_SIZE) {
        return;
    }
    status = Status.RUNNING;
    width = Math.round(sizeMultiplier * width);
    height = Math.round(sizeMultiplier * height);
    
    // 7.获取modelLoader.dataFetcher,transcoder 。他们都与loadProvider 有关。
    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;
    }
    //负责原始数据解码,原始数据解码成bitmap
    ResourceTranscoder<Z, R> transcoder = loadProvider.getTranscoder();
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
    }
    loadedFromMemoryCache = true;
    // 7.1 传入参数,进行实际的图片加载
    loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
            priority, isMemoryCacheable, diskCacheStrategy, this);
    loadedFromMemoryCache = resource != null;
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
    }
}

ModelLoader 从数据源获取原始数据,inputStream-data

DataFetcher 从不同的文件、视频中获取 data。
loadProvider 是什么时候赋值的?
DrawableTypeRequest.java 的 buildProvider()

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;
    }
// buildProvider() 返回FixedLoadProvider
DrawableTypeRequest.java
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 (streamModelLoader == null && fileDescriptorModelLoader == null) {
        return null;
    }

    if (transcoder == null) {
        transcoder = glide.buildTranscoder(resourceClass, transcodedClass);
    }
    //用于图片编解码
    DataLoadProvider<ImageVideoWrapper, Z> dataLoadProvider = glide.buildDataProvider(ImageVideoWrapper.class,
            resourceClass);
    //【重要】:两个modelLoader包装类.
    ImageVideoModelLoader<A> modelLoader = new ImageVideoModelLoader<A>(streamModelLoader,fileDescriptorModelLoader);
    //创建FixedLoadProvider:获取原始图片,解码转码。
    return new FixedLoadProvider<A, ImageVideoWrapper, Z, R>(modelLoader, transcoder, dataLoadProvider);
} 

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容