先介紹一個數據結構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