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相关的源码解析。