先介绍一个数据结构WeakHashMap WeakHashMap大致上就是,通过WeakReference和ReferenceQueue实现的。 WeakHashMap是通过数组table保存Entry(键值对),Entry继承WeakReference,最终继承Reference WeakHashMap还有ReferenceQueue,是一个队列,它会保存被GC回收的“弱键”。 问题:如何自动删除Entry的? 里面有个函数expungeStaleEntries。就是从ReferenceQueue取出数据,然后找到在table中的位置,然后删除,也就是所谓的同步
Glide的into函数
public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) {
Util.assertMainThread();
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
Request previous = target.getRequest();
if (previous != null) {
requestManager.clear(target);
}
requestOptions.lock();
Request request = buildRequest(target);
target.setRequest(request);
requestManager.track(target, request);///////
return target;
}
void track(Target<?> target, Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);//requestTracker里面有WeakHashMap,最后调用下面的begin函数
}
public void begin() {
......
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);//////
} else {
target.getSize(this);
}
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());//一开始加载时显示的drawable
}
......
}
public void onSizeReady(int width, int height) {
......
status = Status.RUNNING;
float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
loadStatus = engine.load(
glideContext,
model,
requestOptions.getSignature(),
this.width,
this.height,
requestOptions.getResourceClass(),
transcodeClass,
priority,
requestOptions.getDiskCacheStrategy(),
requestOptions.getTransformations(),
requestOptions.isTransformationRequired(),
requestOptions.getOptions(),
requestOptions.isMemoryCacheable(),
requestOptions.getUseUnlimitedSourceGeneratorsPool(),
requestOptions.getOnlyRetrieveFromCache(),
this);
......
}
public <R> LoadStatus load(/****/) {
//------------生成key
EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
resourceClass, transcodeClass, options);
//--------------从cache中获取(有数据就返回,没有就往下走)
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
//--------------从activeResources中获取,这是一个Map<Key, WeakReference<EngineResource<?>>>(有数据就返回,没有就往下走)
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
//-------------Map<Key, EngineJob<?>>,从构造函数中赋值(有数据就返回,没有就往下走)
EngineJob<?> current = jobs.get(key);
//------生成EngineJob和DecodeJob
EngineJob<R> engineJob = engineJobFactory.build(key, isMemoryCacheable,
useUnlimitedSourceExecutorPool);
DecodeJob<R> decodeJob = decodeJobFactory.build(/***/);
jobs.put(key, engineJob);//-----缓存变量
engineJob.addCallback(cb);//---添加回调接口
engineJob.start(decodeJob);//-----开始执行decode
//-----EngineJob只是调度,并不执行decode,它做的事只是添加回调接口以及决定让哪个executer来执行runnable
return new LoadStatus(cb, engineJob);
}
DecodeJob继承自Runnable,那就看run方法。run里面调用runWrapped
private void runWrapped() {
switch (runReason) {
case INITIALIZE:
stage = getNextStage(Stage.INITIALIZE);
currentGenerator = getNextGenerator();
runGenerators();
break;
case SWITCH_TO_SOURCE_SERVICE:
runGenerators();
break;
case DECODE_DATA:
decodeFromRetrievedData();
break;
default:
throw new IllegalStateException("Unrecognized run reason: " + runReason);
}
}
runWrapped会调整里面的decode方式之类的,最终调用decodeFromRetrievedData,然后调用decodeFromData,decodeFromFetcher……最后
@Override
public Resource<BitmapDrawable> decode(DataType source, int width, int height, Options options)
throws IOException {
Resource<Bitmap> bitmapResource = decoder.decode(source, width, height, options);
if (bitmapResource == null) {
return null;
}
return LazyBitmapDrawableResource.obtain(resources, bitmapPool, bitmapResource.get());
}
decode那句,找到实现方法ByteBufferBitmapDecoder.decode。一直搜索下去,会看到熟悉的 BitmapFactory.decodeStream(is, null, options); 就是最终的实现(一直要往里面搜索好几层呢)
总结:管理靠的是WeakHashMap,调用看的是EngineJob,执行看的是DecodeJob