前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Glide中request的调用和管理

Glide中request的调用和管理

作者头像
提莫队长
发布2018-05-18 15:19:45
1.2K0
发布2018-05-18 15:19:45
举报
文章被收录于专栏:刘晓杰

先介绍一个数据结构WeakHashMap WeakHashMap大致上就是,通过WeakReference和ReferenceQueue实现的。 WeakHashMap是通过数组table保存Entry(键值对),Entry继承WeakReference,最终继承Reference WeakHashMap还有ReferenceQueue,是一个队列,它会保存被GC回收的“弱键”。 问题:如何自动删除Entry的? 里面有个函数expungeStaleEntries。就是从ReferenceQueue取出数据,然后找到在table中的位置,然后删除,也就是所谓的同步

Glide的into函数

代码语言:javascript
复制
    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

代码语言:javascript
复制
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……最后

代码语言:javascript
复制
@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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年08月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档