Glide中request的調用和管理

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章