Glide源码解析之RequestBuilder

RequestBuilder是什么

它是一个用于处理设置选项和启动加载的类,可以用来监听资源的加载成功与否(RequestListener),加载失败(error)和缩略图(thumbnail),创建Target和Request等。

RequestBuilder怎么创建的

在RequestManger里我们调用load()加载资源的时候,最终会调用RequestBuilder的构造方法把RequestManager和资源的类型赋值进去并创建一个RequestBuilder。

    GlideApp.with(context)
            .load(url)
            .into(imageView)
            
    //RequestManager
    public RequestBuilder load(@Nullable String string) {
        return asDrawable().load(string);
    }
    
    public RequestBuilder asDrawable() {
        return as(Drawable.class);
    }
    
    public  RequestBuilder as(
            @NonNull Class resourceClass) {
        return new RequestBuilder<>(glide, this, resourceClass, context);
    }

load()里面做了什么

这里只是简单的进行赋值,并把isModelSet设置为true。

    public RequestBuilder load(@Nullable String string) {
        return loadGeneric(string);
    }
    
    private RequestBuilder loadGeneric(@Nullable Object model) {
        this.model = model;
        isModelSet = true;
        return this;
    }

into()里面做了什么

首先会判断如果之前没有设置转换比如调用centerCrop()并且允许转换而且imageView的scaleType不为null,则根据它的scaleType设置相应的转换。然后创建了一个ImageViewTarget对象并且传入了into的重载方法。

    public ViewTarget into(@NonNull ImageView view) {
        BaseRequestOptions requestOptions = this;
        if (!requestOptions.isTransformationSet()
                && requestOptions.isTransformationAllowed()
                && view.getScaleType() != null) {
            switch (view.getScaleType()) {
                case CENTER_CROP:
                    requestOptions = requestOptions.clone().optionalCenterCrop();
                    break;
                case CENTER_INSIDE:
                    requestOptions = requestOptions.clone().optionalCenterInside();
                    break;
                case FIT_CENTER:
                case FIT_START:
                case FIT_END:
                    requestOptions = requestOptions.clone().optionalFitCenter();
                    break;
                case FIT_XY:
                    requestOptions = requestOptions.clone().optionalCenterInside();
                    break;
                case CENTER:
                case MATRIX:
                default:
                    // Do nothing.
            }
        }

        return into(
                glideContext.buildImageViewTarget(view, transcodeClass),
                /*targetListener=*/ null,
                requestOptions,
                Executors.mainThreadExecutor());
    }

ImageViewTarget的创建

这里使用了工厂模式来创建ViewTarget,由上面可知我们的资源类型是Drawable,则最终会创建一个DrawableImageViewTarget。

    public  ViewTarget buildImageViewTarget(
            @NonNull ImageView imageView, @NonNull Class transcodeClass) {
        return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
    }
    
    public  ViewTarget buildTarget(@NonNull ImageView view,
        @NonNull Class clazz) {
        if (Bitmap.class.equals(clazz)) {
          return (ViewTarget) new BitmapImageViewTarget(view);
        } else if (Drawable.class.isAssignableFrom(clazz)) {
          return (ViewTarget) new DrawableImageViewTarget(view);
        } else {
          throw new IllegalArgumentException(
          "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
        }
    }

Request的创建

这里通过buildRequest()方法创建了一个Request,并且判断是否和Target之前的Request相等以及如果使用内存缓存的话则回收掉刚刚创建的Request。

    > Y into(
            @NonNull Y target,
            @Nullable RequestListener targetListener,
            Executor callbackExecutor) {
        return into(target, targetListener, /*options=*/ this, callbackExecutor);
    }

    private > Y into(
            @NonNull Y target,
            @Nullable RequestListener targetListener,
            BaseRequestOptions options,
            Executor callbackExecutor) {
        Preconditions.checkNotNull(target);
        if (!isModelSet) {
            //如果没有调用load()方法则会抛异常
            throw new IllegalArgumentException("You must call #load() before calling #into()");
        }

        Request request = buildRequest(target, targetListener, options, callbackExecutor);

        Request previous = target.getRequest(); //调用view.getTag()获取Request
        if (request.isEquivalentTo(previous)
                && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
            request.recycle();
            if (!Preconditions.checkNotNull(previous).isRunning()) {
                previous.begin();   //如果之前的Request不是正在运行的,则开始执行
            }
            return target;
        }

        requestManager.clear(target);   //清除request并释放资源
        target.setRequest(request);     //调用view.setTag()保存request
        requestManager.track(target, request);

        return target;
    }

Request的具体创建

通过几个重载方法,把一堆参数最后传给了SingleRequest的构造方法来创建SingleRequest,由于Request可能会比较多,所以Glide使用了对象池来对SingleRequest进行复用。

    private Request buildRequest(
            Target target,
            @Nullable RequestListener targetListener,
            BaseRequestOptions requestOptions,
            Executor callbackExecutor) {
        return buildRequestRecursive(
                target,
                targetListener,
                /*parentCoordinator=*/ null,
                transitionOptions,
                requestOptions.getPriority(),
                requestOptions.getOverrideWidth(),
                requestOptions.getOverrideHeight(),
                requestOptions,
                callbackExecutor);
    }
    
    private Request buildRequestRecursive(
            Target target,
            @Nullable RequestListener targetListener,
            @Nullable RequestCoordinator parentCoordinator,
            TransitionOptions transitionOptions,
            Priority priority,
            int overrideWidth,
            int overrideHeight,
            BaseRequestOptions requestOptions,
            Executor callbackExecutor) {

        Request mainRequest =
                buildThumbnailRequestRecursive(
                        target,
                        targetListener,
                        parentCoordinator,
                        transitionOptions,
                        priority,
                        overrideWidth,
                        overrideHeight,
                        requestOptions,
                        callbackExecutor);

        if (errorRequestCoordinator == null) {
            return mainRequest;
        }
    }
    
    private Request buildThumbnailRequestRecursive(
            Target target,
            RequestListener targetListener,
            @Nullable RequestCoordinator parentCoordinator,
            TransitionOptions transitionOptions,
            Priority priority,
            int overrideWidth,
            int overrideHeight,
            BaseRequestOptions requestOptions,
            Executor callbackExecutor) {
            return obtainRequest(
                    target,
                    targetListener,
                    requestOptions,
                    parentCoordinator,
                    transitionOptions,
                    priority,
                    overrideWidth,
                    overrideHeight,
                    callbackExecutor);
    }
    
    private Request obtainRequest(
            Target target,
            RequestListener targetListener,
            BaseRequestOptions requestOptions,
            RequestCoordinator requestCoordinator,
            TransitionOptions transitionOptions,
            Priority priority,
            int overrideWidth,
            int overrideHeight,
            Executor callbackExecutor) {
        return SingleRequest.obtain(
                context,
                glideContext,
                model,
                transcodeClass,
                requestOptions,
                overrideWidth,
                overrideHeight,
                priority,
                target,
                targetListener,
                requestListeners,
                requestCoordinator,
                glideContext.getEngine(),
                transitionOptions.getTransitionFactory(),
                callbackExecutor);
    }
    
    public static  SingleRequest obtain(
            Context context,
            GlideContext glideContext,
            Object model,
            Class transcodeClass,
            BaseRequestOptions requestOptions,
            int overrideWidth,
            int overrideHeight,
            Priority priority,
            Target target,
            RequestListener targetListener,
            @Nullable List> requestListeners,
            RequestCoordinator requestCoordinator,
            Engine engine,
            TransitionFactory animationFactory,
            Executor callbackExecutor) {
        @SuppressWarnings("unchecked") SingleRequest request =
                (SingleRequest) POOL.acquire();
        if (request == null) {
            request = new SingleRequest<>();
        }
        request.init(
                context,
                glideContext,
                model,
                transcodeClass,
                requestOptions,
                overrideWidth,
                overrideHeight,
                priority,
                target,
                targetListener,
                requestListeners,
                requestCoordinator,
                engine,
                animationFactory,
                callbackExecutor);
        return request;
    }

到此Target和Request都创建完成了,接着会调用RequestManger的track()把它们传递进去,在上文Glide源码解析之监听生命周期我们介绍过TargetTracker和RequestTracker,他们追踪的Target和Request就是在这里赋值的。

    //RequestManager
    synchronized void track(@NonNull Target target, @NonNull Request request) {
        targetTracker.track(target);
        requestTracker.runRequest(request);
    }
    
    //RequestTracker
   /**
    * 对request开始追踪
    */
    public void runRequest(@NonNull Request request) {
        requests.add(request);
        if (!isPaused) {
            request.begin();    //启动加载
        } else {
          request.clear();
          if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "Paused, delaying request");
          }
          pendingRequests.add(request);
        }
    }

你可能感兴趣的:(Glide源码解析之RequestBuilder)