这块内容比较简单,主要是存(注册)和取
看一下注册:
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,这个单独分析