這塊內容比較簡單,主要是存(註冊)和取
看一下注冊:
registry
.append(ByteBuffer.class, new ByteBufferEncoder())
.append(InputStream.class, new StreamEncoder(arrayPool))
就這兩個,ByteBufferEncoder和StreamEncoder是Encoder的實現類
public <Data> Registry append(@NonNull Class<Data> dataClass, @NonNull Encoder<Data> encoder) {
encoderRegistry.append(dataClass, encoder);
return this;
}
EncoderRegistry中有個list,放進去
private final List<Entry<?>> encoders = new ArrayList<>();
public synchronized <T> void append(@NonNull Class<T> dataClass, @NonNull Encoder<T> encoder) {
encoders.add(new Entry<>(dataClass, encoder));
}
看一下怎麼取:
SourceGenerator 類,對請求回來的InputStream緩存
private void cacheData(Object dataToCache) {
long startTime = LogTime.getLogTime();
try {
//看這句話
Encoder<Object> encoder = helper.getSourceEncoder(dataToCache);
DataCacheWriter<Object> writer =
new DataCacheWriter<>(encoder, dataToCache, helper.getOptions());
originalKey = new DataCacheKey(loadData.sourceKey, helper.getSignature());
helper.getDiskCache().put(originalKey, writer);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(
TAG,
"Finished encoding source to cache"
+ ", key: "
+ originalKey
+ ", data: "
+ dataToCache
+ ", encoder: "
+ encoder
+ ", duration: "
+ LogTime.getElapsedMillis(startTime));
}
} finally {
loadData.fetcher.cleanup();
}
sourceCacheGenerator =
new DataCacheGenerator(Collections.singletonList(loadData.sourceKey), helper, this);
}
DecodeHelper 類
<X> Encoder<X> getSourceEncoder(X data) throws Registry.NoSourceEncoderAvailableException {
return glideContext.getRegistry().getSourceEncoder(data);
}
Registry 類
@NonNull
@SuppressWarnings("unchecked")
public <X> Encoder<X> getSourceEncoder(@NonNull X data) throws NoSourceEncoderAvailableException {
Encoder<X> encoder = encoderRegistry.getEncoder((Class<X>) data.getClass());
if (encoder != null) {
return encoder;
}
throw new NoSourceEncoderAvailableException(data.getClass());
}
EncoderRegistry類,從list中取出對應的Encoder
@Nullable
public synchronized <T> Encoder<T> getEncoder(@NonNull Class<T> dataClass) {
for (Entry<?> entry : encoders) {
if (entry.handles(dataClass)) {
return (Encoder<T>) entry.encoder;
}
}
return null;
}
主要是StreamEncoder,我們分析一下這個類
package com.bumptech.glide.load.model;
import android.util.Log;
import androidx.annotation.NonNull;
import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* An {@link com.bumptech.glide.load.Encoder} that can write an {@link java.io.InputStream} to disk.
*/
public class StreamEncoder implements Encoder<InputStream> {
private static final String TAG = "StreamEncoder";
private final ArrayPool byteArrayPool;
public StreamEncoder(ArrayPool byteArrayPool) {
this.byteArrayPool = byteArrayPool;
}
@Override
public boolean encode(@NonNull InputStream data, @NonNull File file, @NonNull Options options) {
byte[] buffer = byteArrayPool.get(ArrayPool.STANDARD_BUFFER_SIZE_BYTES, byte[].class);
boolean success = false;
OutputStream os = null;
try {
os = new FileOutputStream(file);
int read;
while ((read = data.read(buffer)) != -1) {
os.write(buffer, 0, read);
}
os.close();
success = true;
} catch (IOException e) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Failed to encode data onto the OutputStream", e);
}
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// Do nothing.
}
}
byteArrayPool.put(buffer);
}
return success;
}
}
很簡單,就是把InputStream寫入File裏面,其中用到了ArrayPool,這個單獨分析