Glide4.9.0源码 整体概述(一)

基于源码4.9.0分析,不同版本可能会有所差异,先说整体,后面分节说细节!

Glide最简单的使用就是Glide.with(this).load(url).into(view),我们注意分析这个过程发生了什么。

一、初始化Glide,创建RequestManager

Glide.with(this),这里主要是使用GlideBuilder生成Glide,通过Glide获取RequestManagerRetriever生成一个RequestManager对象。

在初始化Glide的时候,有2种方式获取GlideModule

1、通过编译时注解处理器AnnotationProcessor动态生成。

2、androidmenifest上通过metadata标记。

   //Glide.java

  private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    Context applicationContext = context.getApplicationContext();
    GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
    List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      manifestModules = new ManifestParser(applicationContext).parse();
    }
    ...
  }

二、创建Requestbuilder

load(url)。load方法重载了很多个,举例子说其中一个。

  //RequestManager.java

  public RequestBuilder<Drawable> load(@Nullable Uri uri) {
    return asDrawable().load(uri);
  }
  public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
  }
  public <ResourceType> RequestBuilder<ResourceType> as(
      @NonNull Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
  }
  
  //RequestBuilder.java
  protected RequestBuilder(
      @NonNull Glide glide,
      RequestManager requestManager,
      Class<TranscodeType> transcodeClass,
      Context context) {
    this.glide = glide;
    this.requestManager = requestManager;
    this.transcodeClass = transcodeClass;
    this.context = context;
    this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
    this.glideContext = glide.getGlideContext();

    initRequestListeners(requestManager.getDefaultRequestListeners());
    apply(requestManager.getDefaultRequestOptions());
  }

这里有一点需要注意的,as方法里面的resourceClass参数,在requestBuilder里其实是transcodeClassrequestBuilder的父类BaseRequestOptions里面resourceClass默认值是object.class。那么transcodeClassresourceClass的作用是什么呢?详情可见Glide4.9.0 数据转换设计思路
在这里插入图片描述

三、创建request开始任务

into(view)

//RequestBuilder.java

   private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    Preconditions.checkNotNull(target);
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }

	//这里的target将会给singleRequest用于任务结果回调
    Request request = buildRequest(target, targetListener, options, callbackExecutor); 

    Request previous = target.getRequest();
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      request.recycle();
      // If the request is completed, beginning again will ensure the result is re-delivered,
      // triggering RequestListeners and Targets. If the request is failed, beginning again will
      // restart the request, giving it another chance to complete. If the request is already
      // running, we can let it continue running without interruption.
      if (!Preconditions.checkNotNull(previous).isRunning()) {
        // Use the previous request rather than the new one to allow for optimizations like skipping
        // setting placeholders, tracking and un-tracking Targets, and obtaining View dimensions
        // that are done in the individual Request.
        previous.begin();
      }
      return target;
    }

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

    return target;
  }
这里主要做了3件事情

1、利用递归创建requestGLide buildRequestRecursive 源码解析

2、判断是不是已经存在request,有的话,直接begin()

3、放到requestmanager保存,调用request.begin()

SingleRequest是Request接口的实现类,可以看到在begin方法中有一个onSizeReady的判断。其中overrideWidth和overrideHeigth可以通过RequestOptions.overrideOf方法设置。假如没有设置,将会通过其他方法判断,这里先不展开。
最后就会调用engine.load根据前面的设置参数开始一个任务。

//SingleRequest.java
  @Override
  public synchronized void begin() {
	...
    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      onSizeReady(overrideWidth, overrideHeight);
    } else {
      target.getSize(this);
    }
    ...
  }
  @Override
  public synchronized void onSizeReady(int width, int height) {
    ...
    loadStatus =
        engine.load(
            glideContext,
            model,
            requestOptions.getSignature(),
            this.width,
            this.height,
            requestOptions.getResourceClass(),
            transcodeClass,
            priority,
            requestOptions.getDiskCacheStrategy(),
            requestOptions.getTransformations(),
            requestOptions.isTransformationRequired(),
            requestOptions.isScaleOnlyOrNoTransform(),
            requestOptions.getOptions(),
            requestOptions.isMemoryCacheable(),
            requestOptions.getUseUnlimitedSourceGeneratorsPool(),
            requestOptions.getUseAnimationPool(),
            requestOptions.getOnlyRetrieveFromCache(),
            this,
            callbackExecutor);
     ...
  }
发布了22 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/u012591964/article/details/88529811