Glide源码分析(一)加载R.drawable.*

本博客写于2019.3.8,当前Glide最新版本为4.9.0

添加依赖:

    implementation 'com.github.bumptech.glide:glide:4.9.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'

Glide加载图片的常见用法:

//this 为 FragmentActivity
//t1为一张图片
Glide.with(this).load(R.drawable.t1).into(iv);

为了方便分析,我们将代码分开写:

        RequestManager manager = Glide.with(this);
        RequestBuilder requestBuilder = manager.load(R.drawable.t1);
        requestBuilder.into(iv);

with方法里传入了this,所以应该是做相关的初始化,这里就不粘贴相关代码。

load方法可以直接进RequestManager中查看,这里贴出相关的方法调用,都在RequestManager中

这里重要的是最终将resourceId传入了RequestBuilder中的model,即代码中添加注释那一行。

        public RequestBuilder load (@RawRes @DrawableRes @Nullable Integer resourceId){
            return asDrawable().load(resourceId);
        }
        public RequestBuilder asDrawable () {
            return as(Drawable.class);
        }
        public  RequestBuilder < ResourceType > as(
                @NonNull Class < ResourceType > resourceClass) {
            return new RequestBuilder<>(glide, this, resourceClass, context);
        }

        public RequestBuilder load (@RawRes @DrawableRes @Nullable Integer resourceId)
        {
            return loadGeneric(resourceId).apply(signatureOf(ApplicationVersionSignature.obtain(context)));
        }

        private RequestBuilder loadGeneric (@Nullable Object model){
            //这里实际上就是传进来的R.drawable.t1
            this.model = model;
            isModelSet = true;
            return this;
        }

into方法简化后的相关代码如下

  public ViewTarget into(@NonNull ImageView view) {
    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        Executors.mainThreadExecutor());
  }
  
    private > Y into(
      @NonNull Y target,
      @Nullable RequestListener targetListener,
      BaseRequestOptions options,
      Executor callbackExecutor) {

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

    requestManager.clear(target);
    target.setRequest(request);
    requestManager.track(target, request);

    return target;
  }

这里发现比较有价值的应该就是track,直接再去查看RequestManager中的track方法

  synchronized void track(@NonNull Target target, @NonNull Request request) {
    targetTracker.track(target);
    //这里应该就是要加载图片了
    requestTracker.runRequest(request);
  }

点进去查看runRequest方法:

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

到这里发现由于只走了流程,已经忘记了request是从哪里来了,可以再往前顺一下,在上面就可以看到request是在into方法中赋值的

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

其中一直在buildrequest,这里就不粘贴代码了,最终返回的是SingleRequest,直接再去查看begin方法,简化后的代码如下

  public synchronized void begin() {
    status = Status.WAITING_FOR_SIZE;
    if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
        && canNotifyStatusChanged()) {
      target.onLoadStarted(getPlaceholderDrawable());
    }
  }

发现target又不知道是什么了,再往回顺(这是我自己习惯的看代码的方式,有大佬给指导下这样看有问题吗?)

这里的target只有在init方法中被赋值了,而init方法在刚刚未粘贴出来的buildRequest的一系列代码中被调用过,继续往前顺发现target在into方法中传入的,翻看之前的代码

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

继续查看buildImageViewTarget方法,其中也是一系列的组装,这里不粘贴代码,最终

Glide源码分析(一)加载R.drawable.*_第1张图片

这就是我们要找的target,然后去查看onLoadStarted方法,然而并没有发现这个方法,继续去其父类中寻找

  @Override
  public void onLoadStarted(@Nullable Drawable placeholder) {
    super.onLoadStarted(placeholder);
    setResourceInternal(null);
    setDrawable(placeholder);
  }

这个setDrawable方法让我们看到了希望,点进去看果然:

  public void setDrawable(Drawable drawable) {
    view.setImageDrawable(drawable);
  }

 

你可能感兴趣的:(框架源码)