Glide 源码分析<二>

本文深入解析Glide中DecodeJob类的工作原理,包括数据获取、解析及展示过程。从runWrapped方法入手,分析不同阶段如何获取数据源,并重点探讨SourceGenerator的startNext方法,揭示数据如何层层传递并最终展示。

这里主要分析DecodeJob 这个类,这个类主要负责从服务器拿到数据。先看下runWrapped();方法。

  private void runWrapped() {
     switch (runReason) {
     //开始的第一个阶段
      case INITIALIZE:
      ///getNextStage 的逻辑也是先从磁盘看下能不能够获缓存,如果不行,从SourceGenerator获取。
        stage = getNextStage(Stage.INITIALIZE);
        currentGenerator = getNextGenerator();
        runGenerators();
        break;
      //从磁盘缓存转换为SourceGenerator
      case SWITCH_TO_SOURCE_SERVICE:
        runGenerators();
        break;
     //解析数据。   
      case DECODE_DATA:
        decodeFromRetrievedData();
        break;
      default:
        throw new IllegalStateException("Unrecognized run reason: " + runReason);
    }
  }

接下来主要分析 runGeneroators() 和 decodeFromRetrievedData();

private void runGenerators() {
  currentThread = Thread.currentThread();
  startFetchTime = LogTime.getLogTime();
  boolean isStarted = false;
  //startNext是触发方法。
  while (!isCancelled && currentGenerator != null
      && !(isStarted = currentGenerator.startNext())) {
    stage = getNextStage(stage);
    currentGenerator = getNextGenerator();

    if (stage == Stage.SOURCE) {
      reschedule();
      return;
    }
  }
  // We've run out of stages and generators, give up.
  if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
    notifyFailed();
  }

  // Otherwise a generator started a new load and we expect to be called back in
  // onDataFetcherReady.
}

看下SourceGenerator的 startNext()

public boolean startNext() {
    if (dataToCache != null) {
      Object data = dataToCache;
      dataToCache = null;
      cacheData(data);
    }

    if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
      return true;
    }
    sourceCacheGenerator = null;

    loadData = null;
    boolean started = false;
    //下面接着分析 hasNextModelLoader() 为真。代表有相应的数据解码器。ModelLoader 直译为模型装载,实际上就是数据转换。这里主要是glide初始化会传进来一些模型转载的类,比如
    while (!started && hasNextModelLoader()) {
    //获取到LoadData,这个类包含了获取数据的类,DataFetcher,sourceKey表明需要装载的资源,有些懵逼吧,接着往下看吧,先把能看懂的看完,后续不懂的自然慢看懂了。
      loadData = helper.getLoadData().get(loadDataListIndex++);
      if (loadData != null
          && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
          || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
        started = true;
        //直接装载数据,不同的数据源loadData方式不一样,获取成功后会回调SourceGenerator的onDataReady。onDataReady方法会回调。DecodeJob的onDataFetcherReady。DecodeJob 会对数据进行解析。
//        decodeFromRetrievedData。解析完毕notifyEncodeAndRelease。notifyComplete,调用
//onResourceReady。然后发送到主线程进行显示。
        loadData.fetcher.loadData(helper.getPriority(), this);
      }
    }
    return started;
  }

从对loadData方法分析我们知道,首先是获取数据,然后层层回调解析数据,最后交给target处理。
Glide 这个框架很有意思,虽然说是简单的显示图片这块功能,但由于模块化很厉害,导致整体代码分析起来还是有一定难度。特别是从into方法基本上后面串起来非常长的调用链,这种写法RxJava里面的Observable.subscribe(Observe )如出一辙。
现在总结一下:
从SingleRequest出发。里面有三种不同状态onSizeReady:可以准备开始获取。onResourceReady 数据准备完毕可以开始解析。
主要分析数据获取。过渡到Engine里面的load方法。缓存加载如果不成功,开始执行DecodeJob。
DecodeJob里面主要执行runWrapped。也会判断是从ResourceCacheGenerator,DataCacheGenerator还是SourceGenerator去获取数据。前面两个也是缓存相关产生。如果从网络获取就是走SourceGenerator的startNext。这个方法里面会通过loadData一直回调出去最终到ViewTarget。
等于说数据传出去直接是回到的方式过去的。这就是Glide的大致流程。细节容后分析。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值