轉載請標明出處,維權必究: https://www.cnblogs.com/tangZH/p/12900387.html Glide源碼解析一,初始化 Glide源碼解析二—into方法 Glide源碼解析三(註冊組件) Glide源碼解析四(解碼和轉碼) Glide自定義組件註冊 通過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相關的源碼解析。