Glide 学习计划

熟悉Glide使用

分析Glide.with(context).load(url).into(view) 的内部实现

初始化流程和获取RequestManager

Glide.with(context)会获取一个RequestManager对象. 在这个过程中涉及到

  1. Glide 初始化
  2. RequestManagerRetriever

接下来一步步分析.

Glide.with(this).load(IMG_URL).into(mBinding.ivImg);

@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
  return getRetriever(fragment.getContext()).get(fragment);
}@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  // Context could be null for other reasons (ie the user passes in null), but in practice it will
  // only occur due to errors with the Fragment lifecycle.
  Preconditions.checkNotNull(
      context,
      "You cannot start a load on a not yet attached View or a Fragment where getActivity() "
          + "returns null (which usually occurs when getActivity() is called before the Fragment "
          + "is attached or after the Fragment is destroyed).");
  return Glide.get(context).getRequestManagerRetriever();
}

@NonNull
public static Glide get(@NonNull Context context) {
  if (glide == null) {
    GeneratedAppGlideModule annotationGeneratedModule =
        getAnnotationGeneratedGlideModules(context.getApplicationContext());
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context, annotationGeneratedModule);
      }
    }
  }
  return glide;
}
  1. 通过代码可知, Glide通过单例模式(饿汉式)实现全局只有一个对象, 饿汉式创建对象时,会使用双重检测的方式实现, 根据 volatile 关键可知, 每次使用时从主内存获取最新值,可以防止出现,创建多个对象的情况.
  2. GenerateAppGlideModule 通过反射创建对象, GenerateAppGlideModule是一个抽象类,具体实现是编译阶段生成的一个GenerateAppGlideModuleImpl对象,但是这个对象没有在源码中. Java反射的本质是获取class对象, 通过class对象来操作它的方法和属性.
@GuardedBy("Glide.class")
private static void checkAndInitializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  // In the thread running initGlide(), one or more classes may call Glide.get(context).
  // Without this check, those calls could trigger infinite recursion.
  if (isInitializing) {
    throw new IllegalStateException(
        "You cannot call Glide.get() in registerComponents(),"
            + " use the provided Glide instance instead");
  }
  isInitializing = true;
  initializeGlide(context, generatedAppGlideModule);
  isInitializing = false;
}

method: initializeGlide(Context context, GlideBuilder builder, GeneratedAppGlideModule annotationGeneratedModule) {
    ...
    Glide glide = builder.build(applicationContext);
    ...
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
}

上面代码主要做两件事, 通过构建者模式创建Glide对象, 在ApplicationContext 监听 trimMemory 回调.

@NonNull
  Glide build(@NonNull Context context) {
    if (sourceExecutor == null) {
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }

    if (diskCacheExecutor == null) {
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }

    if (animationExecutor == null) {
      animationExecutor = GlideExecutor.newAnimationExecutor();
    }

    if (memorySizeCalculator == null) {
      memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    }

    if (connectivityMonitorFactory == null) {
      connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }

    if (bitmapPool == null) {
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
        bitmapPool = new LruBitmapPool(size);
      } else {
        bitmapPool = new BitmapPoolAdapter();
      }
    }

    if (arrayPool == null) {
      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }

    if (memoryCache == null) {
      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }

    if (diskCacheFactory == null) {
      diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    if (engine == null) {
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }

    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }

    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        isLoggingRequestOriginsEnabled,
        isImageDecoderEnabledForBitmaps);
  }

这个是创建Glide的主要代码.

  1. 创建GlideExecutor, 线程池对象,会放在Engine对象里面, 这个对象在后面用于创建 EngineJob, DecodeJob, 并执行DecodeJob, DecodeJob执行网络请求, Bitmap处理, 缓存处理和页面展示功能
  2. BitmapPool 对象使用了, Options.inBitmap 属性, 封装了Android复用Bitmap的逻辑
  3. memoryCache Glide 内存缓存机制
  4. connectivityMonitorFactory 网络监听, 断网时会取消所有请求
  5. requestManagerRetriever 设置RequestManager 缓存管理对象
  6. 创建Glide对象.

上面流程走完之后就创建了Glide对象, 内存相关内容之后再说. 其中的一些对象也可以在展开Glide的细节研究时再细说.

回到主线, 这个时候就要获取到RequestManagerRetriever对象, 然后从中获取RequestManager对象. 创建Glide对象时, 会传递一个RequestManagerRetriever对象参数,这个对象就是要获取的RequestManagerRetriever对象.

@NonNull
public RequestManager get(@NonNull Fragment fragment) {
  Preconditions.checkNotNull(
      fragment.getContext(),
      "You cannot start a load on a fragment before it is attached or after it is destroyed");
  if (Util.isOnBackgroundThread()) {
    return get(fragment.getContext().getApplicationContext());
  } else {
    FragmentManager fm = fragment.getChildFragmentManager();
    return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
  }
}

@NonNull
private RequestManager supportFragmentGet(
    @NonNull Context context,
    @NonNull FragmentManager fm,
    @Nullable Fragment parentHint,
    boolean isParentVisible) {
  SupportRequestManagerFragment current =
      getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
  RequestManager requestManager = current.getRequestManager();
  if (requestManager == null) {
    // TODO(b/27524013): Factor out this Glide.get() call.
    Glide glide = Glide.get(context);
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    current.setRequestManager(requestManager);
  }
  return requestManager;
}
@Override

这个方法会先获取一个SupportRequestManagerFragment对象,这个Fragment里面保存有一个RequestManager对象, 如果为空就创建,然后保存到SupportRequestManagerFragment中,再把这个Fragment保存在FragmentManager中,或者是Retriever对象的pendingSupportRequestManagerFragments MAP里面.

RequestManager 对象会和 lifecycle 对象关联, lifecycle 和 Fragment 是关联的, 监听Fragment生命周期的变化, 如果Fragment走到 onStop 或 onDestory 则RequestManager会相应的暂停请求或终止请求并清空相应资源. 如何实现的后面会再研究.

遗留问题, RequestManager的管理问题, 请求取消的实现

RequestBuilder对象

获取RequestManager对象之后调用load(URL)方法之后就会创建RequestBuilder对象

public RequestBuilder<Drawable> load(@Nullable String string) {
  return asDrawable().load(string);
}
public RequestBuilder<Drawable> asDrawable() {
  return as(Drawable.class);
}
public <ResourceType> RequestBuilder<ResourceType> as(
    @NonNull Class<ResourceType> resourceClass) {
  return new RequestBuilder<>(glide, this, resourceClass, context);
}
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());
}
  1. 在上面代码中需要注意的是 asDrawable() 方法, 这个方法会把 RequestBuilder对象的resourceClass设置为Drawable.class, 这个和后面的图片处理有关
  2. RequestBuilder 看名字知道是一个构建者模式的Builder, 所有参数的设置都是通过apply()方法实现
public RequestBuilder<TranscodeType> load(@Nullable String string) {
  return loadGeneric(string);
}
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
  this.model = model;
  isModelSet = true;
  return this;
}

上面方法设置了model, 这个和获取图片的方式有关.至此RequestBuilder的设置就完成了.

into(view)

这个方法涉及到Glide的主要逻辑所以会更复杂.

method: into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        Executors.mainThreadExecutor()) {
        Request request = buildRequest(target, targetListener, options, callbackExecutor);  requestManager.clear(target);
        target.setRequest(request);
        requestManager.track(target, request);  
    }
        
  1. into 方法会创建一个DrawableImageViewTarget对象, 主要是根据 transcodeClass对象实现, 其实就是asDrawable()这个方法实现.Executors.mainThreadExecutor() 通过Looper.MainLoop实现.
  2. buildRequest()方法最终会创建一个SingleRequest对象
  3. 把Request方法RequestManager对象的set集合内,进行管理和取消操作.

其实到这里大体上脉络就出来了, 每个Fragment或Activity就是一个RequestManager对象, 管理当前组件生命周期内的图片请求. 每一个请求对应一个Request对象, 这个对象通过构建者模式创建.

Request 内部逻辑

request 被添加到RequestManager后通过调begin()方法开始

method: begin() {
    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        onSizeReady(overrideWidth, overrideHeight);
    } else {
        target.getSize(this);
    }
    if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
        && canNotifyStatusChanged()) {
        target.onLoadStarted(getPlaceholderDrawable());
    }
}

begin()方法会等待尺寸确定好之后在执行其他请求操作, 如果View还没有确定尺寸会通过设置View.getViewTreeObserver设置监听, 之后会调用onSizeReady()

method: onSizeReady(width, height) {
    status = Status.RUNNING;

    float sizeMultiplier = requestOptions.getSizeMultiplier();
    this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
    this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
    
    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);

    // This is a hack that's only useful for testing right now where loads complete synchronously
    // even though under any executor running on any thread but the main thread, the load would
    // have completed asynchronously.
    if (status != Status.RUNNING) {
        loadStatus = null;
    }
}

最后设置status 为初始化状态且通过engine对象开始加载过程. engine对象是Glide对象创建时设置的.

method: load(args...) {
    // 缓存key
    EngineKey key =
    keyFactory.buildKey(
        model,
        signature,
        width,
        height,
        transformations,
        resourceClass,
        transcodeClass,
        options);
    synchronized (this) {
  memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);
  if (memoryResource == null) {
    return waitForExistingOrStartNewJob(
        glideContext,
        model,
        signature,
        width,
        height,
        resourceClass,
        transcodeClass,
        priority,
        diskCacheStrategy,
        transformations,
        isTransformationRequired,
        isScaleOnlyOrNoTransform,
        options,
        isMemoryCacheable,
        useUnlimitedSourceExecutorPool,
        useAnimationPool,
        onlyRetrieveFromCache,
        cb,
        callbackExecutor,
        key,
        startTime);
  }
}

这个方法会先从缓存中获取key对应的 resource, 如果没获取到就执行 waitForExistingOrStartNewJob()方法, Glide的内存缓存有两部分,分别是ActiveRes 和 MemoryRes.内存缓存相关内容之后再继续分析.

Engine.method: waitForExistingOrStartNewJob() {
    EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
    
    EngineJob<R> engineJob =
        engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);
            
    DecodeJob<R> decodeJob =
        decodeJobFactory.build(
            glideContext,
            model,
            key,
            signature,
            width,
            height,
            resourceClass,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            onlyRetrieveFromCache,
            options,
            engineJob);
            
    jobs.put(key, engineJob);

    engineJob.addCallback(cb, callbackExecutor);
    engineJob.start(decodeJob);
}
  1. waitForExistingOrStartNewJob() 方法是Engine的一个方法, 所有的图片请求对应的就是Engine里的一个Job对象, 这个对象被缓存到了Engine.job属性内.
  2. 所有的请求, 编解码操作都在DecodeJob内实现, EngineJob 是Callback回调的中间处理者

DecodeJob 内部逻辑

我现在虽然知道Glide的内部实现逻辑, 但是一些结构性的东西还是没有理解.

Registry 注册表管理类.

注释信息描述这个类用于管理组合Glide的加载,解码和编码的逻辑,并支持替换和扩展. 因为涉及到的代码太多所以从 model = String.class为出发点进行分析

  • Registry 内部有多个 XXXRegistry类, 用于不同的目的,其中
    • ModelLoaderRegistry 和加载相关
    • EncoderRegistry和ResourceEncoderRegistry 和编码相关
    • ResourceDecoderRegistry 和解码相关
// 在Glide的构造函数中
Glide.method: construct() {
    registry
    .append(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())
    .append(String.class, InputStream.class, new StringLoader.StreamFactory())
    .append(String.class, ParcelFileDescriptor.class, new StringLoader.FileDescriptorFactory())
    .append(
            String.class, AssetFileDescriptor.class, new StringLoader.AssetFileDescriptorFactory())
}

@NonNull
public <Model, Data> Registry append(
    @NonNull Class<Model> modelClass,
    @NonNull Class<Data> dataClass,
    @NonNull ModelLoaderFactory<Model, Data> factory) {
  modelLoaderRegistry.append(modelClass, dataClass, factory);
  return this;
}

上面方法中registry.append()注册表的内容都保存在modelLoaderRegistry中, 这个是和加载相关的逻辑.

ModelLoaderRegistry.method::append(
    @NonNull Class<Model> modelClass,
    @NonNull Class<Data> dataClass,
    @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
  multiModelLoaderFactory.append(modelClass, dataClass, factory);
  cache.clear();
}

MultiModelLoaderFactory:: synchronized <Model, Data> void append(
    @NonNull Class<Model> modelClass,
    @NonNull Class<Data> dataClass,
    @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
  add(modelClass, dataClass, factory, /*append=*/ true);
}

private <Model, Data> void add(
    @NonNull Class<Model> modelClass,
    @NonNull Class<Data> dataClass,
    @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory,
    boolean append) {
  Entry<Model, Data> entry = new Entry<>(modelClass, dataClass, factory);
  entries.add(append ? entries.size() : 0, entry);
}

Entry对象主要是封装了 modelClass , dataClass 和 factory 这三者的关系, 其中 modelClass是数据加载的原始类型, 比如 String, dataClass是根据ModelClass获取到的数据类型,比如InputStream, factory 实现了这种转换关系.举个例子, 看下StringLoader.StreamFactory的实现和使用.

@NonNull
  public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
    List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model));
    if (modelLoaders.isEmpty()) {
      throw new NoModelLoaderAvailableException(model);
    }
    int size = modelLoaders.size();
    boolean isEmpty = true;
    List<ModelLoader<A, ?>> filteredLoaders = Collections.emptyList();
    //noinspection ForLoopReplaceableByForEach to improve perf
    for (int i = 0; i < size; i++) {
      ModelLoader<A, ?> loader = modelLoaders.get(i);
      if (loader.handles(model)) {
        if (isEmpty) {
          filteredLoaders = new ArrayList<>(size - i);
          isEmpty = false;
        }
        filteredLoaders.add(loader);
      }
    }
    if (filteredLoaders.isEmpty()) {
      throw new NoModelLoaderAvailableException(model, modelLoaders);
    }
    return filteredLoaders;
  }
  
@NonNull
  private synchronized <A> List<ModelLoader<A, ?>> getModelLoadersForClass(
      @NonNull Class<A> modelClass) {
    List<ModelLoader<A, ?>> loaders = cache.get(modelClass);
    if (loaders == null) {
      loaders = Collections.unmodifiableList(multiModelLoaderFactory.build(modelClass));
      cache.put(modelClass, loaders);
    }
    return loaders;
  }
  
@NonNull
  synchronized <Model> List<ModelLoader<Model, ?>> build(@NonNull Class<Model> modelClass) {
    try {
      List<ModelLoader<Model, ?>> loaders = new ArrayList<>();
      for (Entry<?, ?> entry : entries) {
        // Avoid stack overflow recursively creating model loaders by only creating loaders in
        // recursive requests if they haven't been created earlier in the chain. For example:
        // A Uri loader may translate to another model, which in turn may translate back to a Uri.
        // The original Uri loader won't be provided to the intermediate model loader, although
        // other Uri loaders will be.
        if (alreadyUsedEntries.contains(entry)) {
          continue;
        }
        if (entry.handles(modelClass)) {
          alreadyUsedEntries.add(entry);
          loaders.add(this.<Model, Object>build(entry));
          alreadyUsedEntries.remove(entry);
        }
      }
      return loaders;
    } catch (Throwable t) {
      alreadyUsedEntries.clear();
      throw t;
    }
  }

上面代码比较多,具体分析如下.

  1. 根据model 获取对应的ModelLoad对象, 这个在Glide构造方法中已经注册过, 加载逻辑相关的都被放到了 ModelLoaderRegistry 中, 这个类由通过 MultiModelLoaderFactory 保存和处理这些注册信息.
  2. 会根据Model对象生成对应的ModelLoader对象, 并保存在ModelLoaderRegistry的cache全局变量中
  3. 遍历entires获取 Entry.handler(model) 为 true 的entry对象, 调用 entry.build(), 把生成的ModelLoader对象保存在list中.
@NonNull
  @SuppressWarnings("unchecked")
  private <Model, Data> ModelLoader<Model, Data> build(@NonNull Entry<?, ?> entry) {
    return (ModelLoader<Model, Data>) Preconditions.checkNotNull(entry.factory.build(this));
  }

调用Entry第三个对象的build()方法, 并把当前MultiModelLoaderFactory当做参数.

/** Factory for loading {@link InputStream}s from Strings. */
public static class StreamFactory implements ModelLoaderFactory<String, InputStream> {
  @NonNull
  @Override
  public ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
    return new StringLoader<>(multiFactory.build(Uri.class, InputStream.class));
  }
  @Override
  public void teardown() {
    // Do nothing.
  }
}

public StringLoader(ModelLoader<Uri, Data> uriLoader) {
    this.uriLoader = uriLoader;
  }

  @Override
  public LoadData<Data> buildLoadData(
      @NonNull String model, int width, int height, @NonNull Options options) {
    Uri uri = parseUri(model);
    if (uri == null || !uriLoader.handles(uri)) {
      return null;
    }
    return uriLoader.buildLoadData(uri, width, height, options);
  }

通过上面代码可知, 调用build()会生成一个ModelLoader对象, 在上面代码中model是string.class, 所以生成的ModelLoader是 StringLoader 对象, 创建这个对象的时候需要给它的 urlLoader 赋值, 这个也是一个ModelLoader对象, 是一个 MultiModelLoader, 这样就通过代理的方式实现了, String -> InputStream 到 uri -> InputStream 的转换.

在Glide的构造方法中, URI的注册表比String多, 但是整体流程上是一样的. 所以就不多说了.

DataFetcherGenerator

Glide 的 DecodeJob 的实现原理是对 DataFetcherGenerator 的链式管理, 去对数据进行加载, 编解码操作, 所以接下来一步步分析他的实现, 现在再看代码不是去了解他内部的实现原理, 而是去明白它的设计理念.

private void runWrapped() {
    switch (runReason) {
      case INITIALIZE:
        stage = getNextStage(Stage.INITIALIZE);
        currentGenerator = getNextGenerator();
        runGenerators();
        break;
      case SWITCH_TO_SOURCE_SERVICE:
        runGenerators();
        break;
      case DECODE_DATA:
        decodeFromRetrievedData();
        break;
      default:
        throw new IllegalStateException("Unrecognized run reason: " + runReason);
    }
  }

  private DataFetcherGenerator getNextGenerator() {
    switch (stage) {
      case RESOURCE_CACHE:
        return new ResourceCacheGenerator(decodeHelper, this);
      case DATA_CACHE:
        return new DataCacheGenerator(decodeHelper, this);
      case SOURCE:
        return new SourceGenerator(decodeHelper, this);
      case FINISHED:
        return null;
      default:
        throw new IllegalStateException("Unrecognized stage: " + stage);
    }
  }

  private void runGenerators() {
    currentThread = Thread.currentThread();
    startFetchTime = LogTime.getLogTime();
    boolean isStarted = false;
    while (!isCancelled
        && currentGenerator != null
        && !(isStarted = currentGenerator.startNext())) {
      stage = getNextStage(stage);
      currentGenerator = getNextGenerator();

      if (stage == Stage.SOURCE) {
        reschedule();
        return;
      }
    }
    // We've run out of stages and generators, give up.
    if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
      notifyFailed();
    }

    // Otherwise a generator started a new load and we expect to be called back in
    // onDataFetcherReady.
  }

先说一下其中的一些属性的作用:

  1. stage 表明了当前的状态, 链表的排列顺序也是根据这个 stage 变化的.
  2. DecodeHelper 是逻辑执行的辅助类.

下面将根据Stage的值变化, 解析DecodeJob 执行逻辑.

/** Where we're trying to decode data from. */
  private enum Stage {
    /** The initial stage. */
    INITIALIZE,
    /** Decode from a cached resource. */
    RESOURCE_CACHE,
    /** Decode from cached source data. */
    DATA_CACHE,
    /** Decode from retrieved source. */
    SOURCE,
    /** Encoding transformed resources after a successful load. */
    ENCODE,
    /** No more viable stages. */
    FINISHED,
  }

Step One : Stage == INITIALIZE

  1. 通过上面的代码知道, INITIALIZE 下一步会给stage 和 currentGenerator 赋值, 这个值是根据 diskCacheStrategy.decodeCachedResource() 来确定的, 这个 diskCacheStrategy 是DiskCacheStrategy.AUTIOMIC, decodeCachedResource() 方法会返回 true.
  2. 之后 stage = Stage.RESOURCE_CACHE, currentGenerator = ResourceCacheGenerator.
  3. stage 的状态变化符合枚举的的顺序,先从缓存中获取,在从DataCahce中取,最后在请求数据
  4. 请求完后通过Callback变化,通知已完成.

Step Two: ResourceCacheGenerator.startNext()

ResourceCacheGenerator.method::startNext() {
    List<Key> sourceIds = helper.getCacheKeys();
    if (sourceIds.isEmpty()) {
      return false;
    }
    List<Class<?>> resourceClasses = helper.getRegisteredResourceClasses();
    if (resourceClasses.isEmpty()) {
      if (File.class.equals(helper.getTranscodeClass())) {
        return false;
      }
      throw new IllegalStateException(
          "Failed to find any load path from "
              + helper.getModelClass()
              + " to "
              + helper.getTranscodeClass());
    }
}
  1. getCacheKeys() 函数通过Glide.Registry 获取对应model的LoadData集合
  2. helper.getRegisteredResourceClasses() 可以获取到解析路径
  3. while 循环几次后退出循环返回 false

Step Three: Stage = DATA_CACHE

如果之前没有请求过数据,那个对应的DiskCache里面也就没对应的图片,所以要走下一步

Step Four: Stage = SOURCE

这个时候 currentGenerator 为 SourceGenerator, 它的作用就是根据model获取到对应的资源,不管是本地Res资源,还是远程服务资源. 获取资源的方式是ModelLoad, 会根据Model 获取到对应的数据, 获取数据的功能由fetch接口实现.

Step Five: LoadPath

LoadPath: 加载路径,在SourceGenerator加载之前就会先判断有没有对应的加载路径,加载路径对应 dataClass, ResourceType 和 Transcode, 但是具体的细节还没了解,最终会把dataclasss转换成Transcode, 这样就能获取到需要的资源, 这次需要的资源类型就是 Drawable.

Step Six: Decode

LoadPath里面有DecodePath, 里面有DecodeResource接口的实现类,Decode 就是用于解码数据,转换成Drawable. 然后再通过callback通知Engine, 最后调用Target的 onSourceReady()方法,给View设置对应的drawable.

这样Glide.with(context).load(url).into(view)的整个流程就结束了。

上一篇:Python教程分享:Redis和Memcache的区别?


下一篇:Android开发---在RecyclerView列表中添加自定义的列表头部与尾部视图