Glide4.9.0 getModelLoaders 源码解析

一、概述

GLide中所有的下载器,解码器,编码器,转换器等都是通过Registry管理的,在生成Registry实例的时候会把内置的所有注册好,以供后续选择使用。

//Registry.java
  private final ModelLoaderRegistry modelLoaderRegistry;
  private final EncoderRegistry encoderRegistry;
  private final ResourceDecoderRegistry decoderRegistry;
  private final ResourceEncoderRegistry resourceEncoderRegistry;
  private final DataRewinderRegistry dataRewinderRegistry;
  private final TranscoderRegistry transcoderRegistry;
  private final ImageHeaderParserRegistry imageHeaderParserRegistry;

二、详解

Glide4.9.0 SourceGenerator 源码解析 提到ModelLoaders是实现model->data的转换。下面我们看看Glide是如何生成可用于特定model的ModelLoaders列表的。

ModelLoaderRegistry为例子,类图如下。可以看到Registry#append方法会通过层层调用直到MultiModelLoaderFactory#append,最后添加到MultiModelLoaderFactory#entries 列表中,实际是由Entry#factory#build创建ModelLoader,Entry#handles方法判断是否可以处理该类型数据。

在这里插入图片描述

那么是在什么时候调用Registry#append注册内置的modelLoader呢?答案是在GLide的构造函数中,并没有完全展示所有,节选了一部分。
Glide(
      @NonNull Context context,
      @NonNull Engine engine,
      @NonNull MemoryCache memoryCache,
      @NonNull BitmapPool bitmapPool,
      @NonNull ArrayPool arrayPool,
      @NonNull RequestManagerRetriever requestManagerRetriever,
      @NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
      int logLevel,
      @NonNull RequestOptions defaultRequestOptions,
      @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
      @NonNull List<RequestListener<Object>> defaultRequestListeners,
      boolean isLoggingRequestOriginsEnabled) {
    ...
    registry = new Registry();
  	...
    registry
        /* Models */
        .register(new InputStreamRewinder.Factory(arrayPool))
        .append(int.class, InputStream.class, resourceLoaderStreamFactory)
        .append(
            int.class,
            ParcelFileDescriptor.class,
            resourceLoaderFileDescriptorFactory)
    ...
  }
Glide是如何从注册好的ModelLoader中找出我们需要使用的。

调用了 modelLoaderRegistry.getModelLoaders(model),直接看下一个方法。

//Registry.java
@NonNull
  public <Model> List<ModelLoader<Model, ?>> getModelLoaders(@NonNull Model model) {
    List<ModelLoader<Model, ?>> result = modelLoaderRegistry.getModelLoaders(model);
    if (result.isEmpty()) {
      throw new NoModelLoaderAvailableException(model);
    }
    return result;
  }
主要是经过2重过滤。
//ModelLoaderRegistry.java
@NonNull
  public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
    //根据model.getClass第一重过滤
    List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model));
    int size = modelLoaders.size();
    boolean isEmpty = true;
    List<ModelLoader<A, ?>> filteredLoaders = Collections.emptyList();
    //noinspection ForLoopReplaceableByForEach to improve perf
    //根据handles方法第二重过滤
    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);
      }
    }
    return filteredLoaders;
  }
  //可以看到第一重过滤是由multiModelLoaderFactory.build(modelClass)执行的。
  @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;
  }
第一重过滤
//MultiModelLoaderFactory.java
@NonNull
  synchronized <Model> List<ModelLoader<Model, ?>> build(@NonNull Class<Model> modelClass) {
    try {
      List<ModelLoader<Model, ?>> loaders = new ArrayList<>();
      for (Entry<?, ?> entry : entries) {
       
        if (alreadyUsedEntries.contains(entry)) {
          continue;
        }
		//判断entry.modelclass是不是modelclass的父类。
        if (entry.handles(modelClass)) {
          alreadyUsedEntries.add(entry);
          //调用entry.factory.build(this)
          //entry.factory是ModelLoaderFactory接口。
          //这里根据不同的ModelLoaderFactory实现类,会有不同的表现。
          //主要功能就是创建一个modelloader。
          //这里有一个注意点是MultiModelLoader的概念。
          loaders.add(this.<Model, Object>build(entry));
          alreadyUsedEntries.remove(entry);
        }
      }
      return loaders;
    } catch (Throwable t) {
      alreadyUsedEntries.clear();
      throw t;
    }
  }
第二重过滤

是由具体的ModelLoader接口实现类自己实现,不同的实现类不一样,例如:

//DataUriLoader.java
@Override
  public boolean handles(@NonNull Model model) {
    // We expect Model to be a Uri or a String, both of which implement toString() efficiently. We
    // should reconsider this implementation before adding any new Model types.
    return model.toString().startsWith(DATA_SCHEME_IMAGE);
  }
发布了22 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

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