Glide源码解析三(注册组件)

转载请标明出处,维权必究: https://www.cnblogs.com/tangZH/p/12900387.html

 

本文基于Glide 4.11.0

 

这里说的注册便是Glide初始化过程中,对解码器,编码器等的注册。

具体初始化过程可以看http://77blogs.com/?p=269

 

本文主要讲初始化过程中,注册到底做了什么,注册的这些又存储在哪里。

比如源码中的下面代码:

registry
        .append(ByteBuffer.class, new ByteBufferEncoder())
        .append(InputStream.class, new StreamEncoder(arrayPool))
        /* Bitmaps */
        .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
        .append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder);

可以在glide初始化过程中看到执行注册的是Register对象,我们可以进去看看。

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;

可以看到很多个相关的类。

ModelLoaderRegistry :注册模型加载器相关

EncoderRegistry:注册编码器相关

ResourceDecoderRegistry:注册资源解码器相关

ResourceEncoderRegistry :注册资源编码器相关

DataRewinderRegistry:数据类型对应的资源数据相关

TranscoderRegistry:注册转码器相关

ImageHeaderParserRegistry :解析图片文件头的解析器相关

 

一、模型加载器

如源码中:

registry
        .append(int.class, InputStream.class, resourceLoaderStreamFactory)

将int类型加载为InputStream类型,加载器为resourceLoaderStreamFactory,比如我们加载图片的时候传递给glide的是一个资源id,那么glide会运用resourceLoaderStreamFactory

模型加载器将该资源id加载为InputStream,之后再是解码的过程。

 

进去发现它会调用:

modelLoaderRegistry.append(modelClass, dataClass, factory);

 

接着在ModelLoaderRegistry里面会调用:

multiModelLoaderFactory.append(modelClass, dataClass, factory);

 

追溯代码最终到这里:

  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

public Entry(
        @NonNull Class<Model> modelClass,
        @NonNull Class<Data> dataClass,
        @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
      this.modelClass = modelClass;
      this.dataClass = dataClass;
      this.factory = factory;
    }

然后存放于一个list里面,这个list在multiModelLoaderFactory里。

private final List<Entry<?, ?>> entries = new ArrayList<>();

 

二、编码器

如源码中的:

registry
        .append(ByteBuffer.class, new ByteBufferEncoder())

将ByteBuffer类型数据编码为一个文件存放下来,编码器为ByteBufferEncoder

 

进去里面可以发现他调用了EncoderRegistry的append方法,然后构造一个Entry,存放在EncoderRegistry的一个集合里面:

private final List<Entry<?>> encoders = new ArrayList<>();

 

三、资源解码器

如源码中:

registry
        .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)

将ByteBuffer类型解码为Bitmap类型,解码器为byteBufferBitmapDecoder

而Registry.BUCKET_BITMAP代表的是一种类型,因为每种类型可以对应多种解码器,如:

.append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder);

 

我们最终来到这个方法:

public synchronized <T, R> void append(
    @NonNull String bucket,
    @NonNull ResourceDecoder<T, R> decoder,
    @NonNull Class<T> dataClass,
    @NonNull Class<R> resourceClass) {
  getOrAddEntryList(bucket).add(new Entry<>(dataClass, resourceClass, decoder));
}

getOrAddEntryList返回的是一个List<Entry<?, ?>>类型,里面存放着构造好的Entry实体类。这个List其实存放的是同样类型的解码器,比如都是Registry.BUCKET_BITMAP类型的,而这个整个List存放在一个map里面,key就是Registry.BUCKET_BITMAP。

 

private final Map<String, List<Entry<?, ?>>> decoders = new HashMap<>();

 

private synchronized List<Entry<?, ?>> getOrAddEntryList(@NonNull String bucket) {
  if (!bucketPriorityList.contains(bucket)) {
    // Add this unspecified bucket as a low priority bucket.
    bucketPriorityList.add(bucket);
  }
  List<Entry<?, ?>> entries = decoders.get(bucket);
  if (entries == null) {
    entries = new ArrayList<>();
    decoders.put(bucket, entries);
  }
  return entries;
}

getOrAddEntryList方法里面,通过bucketPriorityList判断是否已经有了一个这个类型的list,有的话直接从map获取该list,然后将注册的放进去。

 

四、资源编码器

如源码中:

如:

.append(GifDrawable.class, new GifDrawableEncoder())

将GifDrawable资源类型进行编码,编码器为:GifDrawableEncoder,GifDrawableEncoder里面主要是将gif数据保存为文件,对gif进行磁盘缓存的时候便需要用到这个编码器。

存储的过程与之前的类似,存在list中。

 

五、转码器

如源码中的:

register.register(Bitmap.class, BitmapDrawable.class, new BitmapDrawableTranscoder(resources))

将Bitmap转化为BitmapDrawable,转码器为BitmapDrawableTranscoder

 

存储过程类似。

 

六、ImageHeaderParserRegistry 

如源码中的:

registry.register(new DefaultImageHeaderParser());

默认的image文件头的解析器,可以由这个解析器判断图片类型,这也是用同样的代码能够加载动图与静图的原因。

 

存储过程类似。

 

至于DataRewinderRegistry 还未细看,后面再来补充,后面也会继续更新Glide相关的源码解析。

 

热门相关:总裁别再玩了