美文网首页
2019-11-19Glide 源码流程分析<1>

2019-11-19Glide 源码流程分析<1>

作者: 猫KK | 来源:发表于2019-11-19 17:48 被阅读0次

    注:这是基于4.10.0的源码
    先上一张时序图:


    Glide-时序图.png

    先来看glide使用

            Glide.with(this)
                .load("http://goo.gl/gEgYUd")
                .into(iv_test)
    

    into 之前主要是做一些初始化操作,构建单例的Glide,创建空的fragment来感知生命周期,这里就不做介绍来看into之后做了什么

      @NonNull
      public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
        //检查线程
        Util.assertMainThread();
        //判断null
        Preconditions.checkNotNull(view);
        //判断view自身是否设置了ScaleType
        BaseRequestOptions<?> requestOptions = this;
        if (!requestOptions.isTransformationSet()
            && requestOptions.isTransformationAllowed()
            && view.getScaleType() != null) {
          // Clone in this method so that if we use this RequestBuilder to load into a View and then
          // into a different target, we don't retain the transformation applied based on the previous
          // View's scale type.
          switch (view.getScaleType()) {
            case CENTER_CROP:
              requestOptions = requestOptions.clone().optionalCenterCrop();
              break;
            case CENTER_INSIDE:
              requestOptions = requestOptions.clone().optionalCenterInside();
              break;
            case FIT_CENTER:
            case FIT_START:
            case FIT_END:
              requestOptions = requestOptions.clone().optionalFitCenter();
              break;
            case FIT_XY:
              requestOptions = requestOptions.clone().optionalCenterInside();
              break;
            case CENTER:
            case MATRIX:
            default:
              // Do nothing.
          }
        }
        //调用into方法
         //注意第一个参数,返回的是一个DrawableImageViewTarget对象
        return into(
            glideContext.buildImageViewTarget(view, transcodeClass),
            /*targetListener=*/ null,
            requestOptions,
            Executors.mainThreadExecutor());
      }
    
      @NonNull
      @Synthetic
      <Y extends Target<TranscodeType>> Y into(
          @NonNull Y target,
          @Nullable RequestListener<TranscodeType> targetListener,
          Executor callbackExecutor) {
        //继续调用自身
        return into(target, targetListener, /*options=*/ this, callbackExecutor);
      }
    
      private <Y extends Target<TranscodeType>> Y into(
          @NonNull Y target,
          @Nullable RequestListener<TranscodeType> targetListener,
          BaseRequestOptions<?> options,
          Executor callbackExecutor) {
        Preconditions.checkNotNull(target);
        if (!isModelSet) {
          throw new IllegalArgumentException("You must call #load() before calling #into()");
        }
        //构建一个请求
        Request request = buildRequest(target, targetListener, options, callbackExecutor);
        //从target中获取请求
        Request previous = target.getRequest();
         //请求是同一个
        if (request.isEquivalentTo(previous)
            && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
          if (!Preconditions.checkNotNull(previous).isRunning()) {
           //开启请求
            previous.begin();
          }
          return target;
        }
        //不是同一个,清除
        requestManager.clear(target);
        //将请求设置到target
        target.setRequest(request);
        //添加到requestManager中,并开启请求,也就是request.begin方法
        //就是这一个,将请求绑定生命周期
        requestManager.track(target, request);
        return target;
      }
    

    通过上面可以知道,主要就是构建一个request,然后调用begin方法,下面看如何构建请求

      private Request buildRequest(
          Target<TranscodeType> target,
          @Nullable RequestListener<TranscodeType> targetListener,
          BaseRequestOptions<?> requestOptions,
          Executor callbackExecutor) {
        return buildRequestRecursive(
            /*requestLock=*/ new Object(),
            target,
            targetListener,
            /*parentCoordinator=*/ null,
            transitionOptions,
            requestOptions.getPriority(),
            requestOptions.getOverrideWidth(),
            requestOptions.getOverrideHeight(),
            requestOptions,
            callbackExecutor);
      }
    
      private Request buildRequestRecursive(
          Object requestLock,
          Target<TranscodeType> target,
          @Nullable RequestListener<TranscodeType> targetListener,
          @Nullable RequestCoordinator parentCoordinator,
          TransitionOptions<?, ? super TranscodeType> transitionOptions,
          Priority priority,
          int overrideWidth,
          int overrideHeight,
          BaseRequestOptions<?> requestOptions,
          Executor callbackExecutor) {
    
        // Build the ErrorRequestCoordinator first if necessary so we can update parentCoordinator.
        ErrorRequestCoordinator errorRequestCoordinator = null;
        //默认为null
        if (errorBuilder != null) {
          errorRequestCoordinator = new ErrorRequestCoordinator(requestLock, parentCoordinator);
          parentCoordinator = errorRequestCoordinator;
        }
    
        Request mainRequest =
            buildThumbnailRequestRecursive(
                requestLock,
                target,
                targetListener,
                parentCoordinator,
                transitionOptions,
                priority,
                overrideWidth,
                overrideHeight,
                requestOptions,
                callbackExecutor);
    
     //....
      }
    
      private Request buildThumbnailRequestRecursive(
          Object requestLock,
          Target<TranscodeType> target,
          RequestListener<TranscodeType> targetListener,
          @Nullable RequestCoordinator parentCoordinator,
          TransitionOptions<?, ? super TranscodeType> transitionOptions,
          Priority priority,
          int overrideWidth,
          int overrideHeight,
          BaseRequestOptions<?> requestOptions,
          Executor callbackExecutor) {
        //....
          //假设没有做任何的操作,则直接返回这个
          return obtainRequest(
              requestLock,
              target,
              targetListener,
              requestOptions,
              parentCoordinator,
              transitionOptions,
              priority,
              overrideWidth,
              overrideHeight,
              callbackExecutor);
        }
      }
    

    先假设没有配置缩略图什么的,所以直接返回的就是obtainRequest()方法返回的

      private Request obtainRequest(
          Object requestLock,
          Target<TranscodeType> target,
          RequestListener<TranscodeType> targetListener,
          BaseRequestOptions<?> requestOptions,
          RequestCoordinator requestCoordinator,
          TransitionOptions<?, ? super TranscodeType> transitionOptions,
          Priority priority,
          int overrideWidth,
          int overrideHeight,
          Executor callbackExecutor) {
        return SingleRequest.obtain(
            context,
            glideContext,
            requestLock,
            model,
            transcodeClass,
            requestOptions,
            overrideWidth,
            overrideHeight,
            priority,
            target,
            targetListener,
            requestListeners,
            requestCoordinator,
            glideContext.getEngine(),
            transitionOptions.getTransitionFactory(),
            callbackExecutor);
      }
    
      public static <R> SingleRequest<R> obtain(
          Context context,
          GlideContext glideContext,
          Object requestLock,
          Object model,
          Class<R> transcodeClass,
          BaseRequestOptions<?> requestOptions,
          int overrideWidth,
          int overrideHeight,
          Priority priority,
          Target<R> target,
          RequestListener<R> targetListener,
          @Nullable List<RequestListener<R>> requestListeners,
          RequestCoordinator requestCoordinator,
          Engine engine,
          TransitionFactory<? super R> animationFactory,
          Executor callbackExecutor) {
        return new SingleRequest<>(
            context,
            glideContext,
            requestLock,
            model,
            transcodeClass,
            requestOptions,
            overrideWidth,
            overrideHeight,
            priority,
            target,
            targetListener,
            requestListeners,
            requestCoordinator,
            engine,
            animationFactory,
            callbackExecutor);
      }
    

    所以这个request就是一个SingleRequest对象,进入SingleRequest中的begin方法

      @Override
      public void begin() {
        synchronized (requestLock) {
          assertNotCallingCallbacks();
          stateVerifier.throwIfRecycled();
          startTime = LogTime.getLogTime();
          //判断model是否赋值,注意这个model是我们调用load()中传进来的
          //这里传进来的是一个string类型的地址
          if (model == null) {
            if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
              width = overrideWidth;
              height = overrideHeight;
            }
            // Only log at more verbose log levels if the user has set a fallback drawable, because
            // fallback Drawables indicate the user expects null models occasionally.
            int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
            //调用失败方法
            onLoadFailed(new GlideException("Received null model"), logLevel);
            return;
          }
          //如果已经在运行,抛出异常
          if (status == Status.RUNNING) {
            throw new IllegalArgumentException("Cannot restart a running request");
          }
    
          //如果已经完成,调用onResourceReady
          if (status == Status.COMPLETE) {
            onResourceReady(resource, DataSource.MEMORY_CACHE);
            return;
          }
    
          // 将状态至为获取尺寸
          status = Status.WAITING_FOR_SIZE;
          //如果尺寸可用,调用onSizeReady方法
          if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
            onSizeReady(overrideWidth, overrideHeight);
          } else {
            //调用获取尺寸,最后会回调到onSizeReady方法
            target.getSize(this);
          }
    
          if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
              && canNotifyStatusChanged()) {
            target.onLoadStarted(getPlaceholderDrawable());
          }
          if (IS_VERBOSE_LOGGABLE) {
            logV("finished run method in " + LogTime.getElapsedMillis(startTime));
          }
        }
      }
    

    不过尺寸是否可用,在的到尺寸之后都会回调到onSizeReady()方法

      @Override
      public void onSizeReady(int width, int height) {
        stateVerifier.throwIfRecycled();
        synchronized (requestLock) {
          if (IS_VERBOSE_LOGGABLE) {
            logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
          }
          //如果不是获取尺寸回调,返回
          if (status != Status.WAITING_FOR_SIZE) {
            return;
          }
          //将状态至为运行汇总
          status = Status.RUNNING;
          //获取宽高
          float sizeMultiplier = requestOptions.getSizeMultiplier();
          this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
          this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
    
          if (IS_VERBOSE_LOGGABLE) {
            logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));
          }
          //调用load,获取
          loadStatus =
              engine.load(
                  glideContext,
                  model,
                  requestOptions.getSignature(),
                  this.width,
                  this.height,
                  requestOptions.getResourceClass(),
                  transcodeClass,
                  priority,
                  requestOptions.getDiskCacheStrategy(),
                  requestOptions.getTransformations(),
                  requestOptions.isTransformationRequired(),
                  requestOptions.isScaleOnlyOrNoTransform(),
                  requestOptions.getOptions(),
                  requestOptions.isMemoryCacheable(),
                  requestOptions.getUseUnlimitedSourceGeneratorsPool(),
                  requestOptions.getUseAnimationPool(),
                  requestOptions.getOnlyRetrieveFromCache(),
                  this,
                  callbackExecutor);
    
      //....
        }
      }
    

    走到了engine.load方法

      public <R> LoadStatus load(
          GlideContext glideContext,
          Object model,
          Key signature,
          int width,
          int height,
          Class<?> resourceClass,
          Class<R> transcodeClass,
          Priority priority,
          DiskCacheStrategy diskCacheStrategy,
          Map<Class<?>, Transformation<?>> transformations,
          boolean isTransformationRequired,
          boolean isScaleOnlyOrNoTransform,
          Options options,
          boolean isMemoryCacheable,
          boolean useUnlimitedSourceExecutorPool,
          boolean useAnimationPool,
          boolean onlyRetrieveFromCache,
          ResourceCallback cb,
          Executor callbackExecutor) {
        long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;
        //构建一个key
        EngineKey key =
            keyFactory.buildKey(
                model,
                signature,
                width,
                height,
                transformations,
                resourceClass,
                transcodeClass,
                options);
    
        EngineResource<?> memoryResource;
        synchronized (this) {
          //从内存中获取
          memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);
    
          if (memoryResource == null) {
            //内存中没有获取到,尝试从本地或者网络中获取
            return waitForExistingOrStartNewJob(
                glideContext,
                model,
                signature,
                width,
                height,
                resourceClass,
                transcodeClass,
                priority,
                diskCacheStrategy,
                transformations,
                isTransformationRequired,
                isScaleOnlyOrNoTransform,
                options,
                isMemoryCacheable,
                useUnlimitedSourceExecutorPool,
                useAnimationPool,
                onlyRetrieveFromCache,
                cb,
                callbackExecutor,
                key,
                startTime);
          }
        }
    
        //内存中获取成功,回调出去
        cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);
        return null;
      }
    

    loadFromMemory()方法就是从内存中获取资源,默认在内存中没有,所以调用waitForExistingOrStartNewJob()方法获取

      private <R> LoadStatus waitForExistingOrStartNewJob(
          GlideContext glideContext,
          Object model,
          Key signature,
          int width,
          int height,
          Class<?> resourceClass,
          Class<R> transcodeClass,
          Priority priority,
          DiskCacheStrategy diskCacheStrategy,
          Map<Class<?>, Transformation<?>> transformations,
          boolean isTransformationRequired,
          boolean isScaleOnlyOrNoTransform,
          Options options,
          boolean isMemoryCacheable,
          boolean useUnlimitedSourceExecutorPool,
          boolean useAnimationPool,
          boolean onlyRetrieveFromCache,
          ResourceCallback cb,
          Executor callbackExecutor,
          EngineKey key,
          long startTime) {
        //获取缓存的EngineJob
        EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
        if (current != null) {
          //添加回调
          current.addCallback(cb, callbackExecutor);
          if (VERBOSE_IS_LOGGABLE) {
            logWithTimeAndKey("Added to existing load", startTime, key);
          }
          return new LoadStatus(cb, current);
        }
        //构建EngineJob
        EngineJob<R> engineJob =
            engineJobFactory.build(
                key,
                isMemoryCacheable,
                useUnlimitedSourceExecutorPool,
                useAnimationPool,
                onlyRetrieveFromCache);
        //构建DecodeJob,其中DecodeJob是实现了Runnable
        DecodeJob<R> decodeJob =
            decodeJobFactory.build(
                glideContext,
                model,
                key,
                signature,
                width,
                height,
                resourceClass,
                transcodeClass,
                priority,
                diskCacheStrategy,
                transformations,
                isTransformationRequired,
                isScaleOnlyOrNoTransform,
                onlyRetrieveFromCache,
                options,
                engineJob);
        //放到缓存中
        jobs.put(key, engineJob);
        //添加回到
        engineJob.addCallback(cb, callbackExecutor);
        //开始执行
        engineJob.start(decodeJob);
    
        if (VERBOSE_IS_LOGGABLE) {
          logWithTimeAndKey("Started new load", startTime, key);
        }
        return new LoadStatus(cb, engineJob);
      }
    

    上面中engineJob.start(decodeJob);就是通过一个线程池来执行Runnable,因为DecodeJob实现了Runnable,所以会走到DecodeJob的run方法中

      @Override
      public void run() {
          //...
         
          runWrapped();
          //.....
      }
    
      private void runWrapped() {
        //runReason默认为INITIALIZE
        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);
        }
      }
    

    上面这里就有点像策略模式,通过不同的策略来获取资源,也就是通过本地或网络获取图片,获取到对应的策略之后调用runGenerators()方法

      private void runGenerators() {
        currentThread = Thread.currentThread();
        startFetchTime = LogTime.getLogTime();
        boolean isStarted = false;
        //调用对应的startNext()方法
        while (!isCancelled
            && currentGenerator != null
            && !(isStarted = currentGenerator.startNext())) {
          //如果startNext()返回false,则获取下一个Generator,
          //也就是策略,然后在调用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.
      }
    

    根据getNextGenerator()方法返回的Generator来看,当第一次请求是,会走到SourceGenerator的startNext()方法中,也就是从网络中获取,我们看SourceGenerator的startNext()方法

      @Override
      public boolean startNext() {
        //第一次dataToCache为null
        if (dataToCache != null) {
          Object data = dataToCache;
          dataToCache = null;
          cacheData(data);
        }
        //sourceCacheGenerator也为null
        if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
          return true;
        }
        sourceCacheGenerator = null;
    
        loadData = null;
        boolean started = false;
        //通过while,来获取
        while (!started && hasNextModelLoader()) {
          //获取可用的获取资源列表
          loadData = helper.getLoadData().get(loadDataListIndex++);
          //判断是否可用
          if (loadData != null
              && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
                  || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
            //可用将started至为true
            started = true;
            //获取资源
            loadData.fetcher.loadData(helper.getPriority(), this);
          }
        }
        return started;
      }
    

    其中这里是我觉得比较绕的地方,就是如何判断获取的是哪个,先来看helper.getLoadData()获取的列表是什么

      List<LoadData<?>> getLoadData() {
        if (!isLoadDataSet) {
          isLoadDataSet = true;
          loadData.clear();
          //获取前面注册的,这里的model就是我们的string类型地址
          List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
          //noinspection ForLoopReplaceableByForEach to improve perf
          for (int i = 0, size = modelLoaders.size(); i < size; i++) {
            ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
            //注意这里,调用了buildLoadData()方法
            LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
            if (current != null) {
              loadData.add(current);
            }
          }
        }
        return loadData;
      }
    

    又通过glideContext.getRegistry().getModelLoaders(model);来获取

      @NonNull
      public <Model> List<ModelLoader<Model, ?>> getModelLoaders(@NonNull Model model) {
        //通过getModelLoaders方法获取
        List<ModelLoader<Model, ?>> result = modelLoaderRegistry.getModelLoaders(model);
        if (result.isEmpty()) {
          throw new NoModelLoaderAvailableException(model);
        }
        return result;
      }
    
      @NonNull
      public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
        //通过getModelLoadersForClass获取
        List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model));
        int size = modelLoaders.size();
        boolean isEmpty = true;
        List<ModelLoader<A, ?>> filteredLoaders = Collections.emptyList();
        //noinspection ForLoopReplaceableByForEach to improve perf
        for (int i = 0; i < size; i++) {
          ModelLoader<A, ?> loader = modelLoaders.get(i);
          //判断是否可用
          if (loader.handles(model)) {
            if (isEmpty) {
              filteredLoaders = new ArrayList<>(size - i);
              isEmpty = false;
            }
            //如果可用,添加到filteredLoaders中
            filteredLoaders.add(loader);
          }
        }
        return filteredLoaders;
      }
    

    这里又通过getModelLoadersForClass()方法来获取

      @NonNull
      private synchronized <A> List<ModelLoader<A, ?>> getModelLoadersForClass(
          @NonNull Class<A> modelClass) {
        //通过缓存获取
        List<ModelLoader<A, ?>> loaders = cache.get(modelClass);
        if (loaders == null) {
          //缓存为null,通过multiModelLoaderFactory.build(modelClass)方法获取
          //其中modelClass为String.class
          loaders = Collections.unmodifiableList(multiModelLoaderFactory.build(modelClass));
          cache.put(modelClass, loaders);
        }
        return loaders;
      }
    

    又通过multiModelLoaderFactory.build(modelClass)来获取,需要注意的是modelClass为String.class

      @NonNull
      synchronized <Model> List<ModelLoader<Model, ?>> build(@NonNull Class<Model> modelClass) {
        try {
          List<ModelLoader<Model, ?>> loaders = new ArrayList<>();
          //循环entries
          for (Entry<?, ?> entry : entries) {
            //如果已经添加了,continue
            if (alreadyUsedEntries.contains(entry)) {
              continue;
            }
            //判断是否可用
            if (entry.handles(modelClass)) {
              alreadyUsedEntries.add(entry);
              //如果可用,调用build方法,build方法就是:entry.factory.build(this)
              loaders.add(this.<Model, Object>build(entry));
              alreadyUsedEntries.remove(entry);
            }
          }
          return loaders;
        } catch (Throwable t) {
          alreadyUsedEntries.clear();
          throw t;
        }
      }
    

    其中entries是在Glide构造方法中添加数据的

    //构造方法中,就是通过append来给前面的entries数组添加值的
    registry
            .append(ByteBuffer.class, new ByteBufferEncoder())
    //...
    

    根据前面的,因为modelClass为String.class,所以只需要找下面这些

    .append(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())
    .append(String.class, InputStream.class, new StringLoader.StreamFactory())
    .append(String.class, ParcelFileDescriptor.class, new StringLoader.FileDescriptorFactory())
    .append(
                String.class, AssetFileDescriptor.class, new StringLoader.AssetFileDescriptorFactory())
    

    其中第三个参数就是factory,所以这里添加的就是这里对应的factory中build方法返回的然后现在往回走,回到helper.getLoadData()方法中

      List<LoadData<?>> getLoadData() {
        if (!isLoadDataSet) {
          isLoadDataSet = true;
          loadData.clear();
          //我们已经知道了这个list里的值是什么了
          List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
          //noinspection ForLoopReplaceableByForEach to improve perf
          for (int i = 0, size = modelLoaders.size(); i < size; i++) {
            ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
            //调用buildLoadData()方法
            LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
            if (current != null) {
              loadData.add(current);
            }
          }
        }
        return loadData;
      }
    

    然后再调用buildLoadData()方法,就是前面我们看的factory.build()返回值的buildLoadData()方法,我以第一个来举例,也就是DataUrlLoader.StreamFactory<String>()

        @NonNull
        @Override
        public ModelLoader<Model, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
          //返回DataUrlLoader对象
          return new DataUrlLoader<>(opener);
        }
    

    这个返回的是一个DataUrlLoader对象

      public DataUrlLoader(DataDecoder<Data> dataDecoder) {
        this.dataDecoder = dataDecoder;
      }
    
      @Override
      public LoadData<Data> buildLoadData(
          @NonNull Model model, int width, int height, @NonNull Options options) {
        //正常会走来这里
        return new LoadData<>(
            new ObjectKey(model), new DataUriFetcher<>(model.toString(), dataDecoder));
      }
    
      @Override
      public boolean handles(@NonNull Model model) {
        //注意这里返回的false
        return model.toString().startsWith(DATA_SCHEME_IMAGE);
      }
    

    正常会走buildLoadData()方法,但是这里handles()方法判断返回的是false,前面我们在添加的时候会判断handles()方法,如果返回false,则不添加,所以这个不符合,会走到下一个,也就是StringLoader.StreamFactory()中

        @NonNull
        @Override
        public ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
          //返回StringLoader,注意这里里面又调用了multiFactory.build(Uri.class, InputStream.class)
          //相当于又从新找了一遍
          return new StringLoader<>(multiFactory.build(Uri.class, InputStream.class));
        }
    

    返回StringLoader,去看StringLoader

      public StringLoader(ModelLoader<Uri, Data> uriLoader) {
        this.uriLoader = uriLoader;
      }
    
      @Override
      public LoadData<Data> buildLoadData(
          @NonNull String model, int width, int height, @NonNull Options options) {
        Uri uri = parseUri(model);
        //判断又判断了handles
        if (uri == null || !uriLoader.handles(uri)) {
          return null;
        }
        //返回的是buildLoadData()方法
        return uriLoader.buildLoadData(uri, width, height, options);
      }
    
      @Override
      public boolean handles(@NonNull String model) {
        //这里返回true
        return true;
      }
    

    所以,又调了一遍multiFactory.build(Uri.class, InputStream.class),注意这里的类型变成了Uri.class, InputStream.class,所以我们在去Glide构造方法中找对应的

    .append(Uri.class, InputStream.class, new DataUrlLoader.StreamFactory<Uri>())
    .append(Uri.class, InputStream.class, new HttpUriLoader.Factory())
    .append(Uri.class, InputStream.class, new AssetUriLoader.StreamFactory(context.getAssets()))
    .append(Uri.class, InputStream.class, new MediaStoreImageThumbLoader.Factory(context))
            .append(Uri.class, InputStream.class, new MediaStoreVideoThumbLoader.Factory(context))
            .append(Uri.class, InputStream.class, new UriLoader.StreamFactory(contentResolver))
    .append(Uri.class, InputStream.class, new UrlUriLoader.StreamFactory())
    

    然后又通过factory.build()的返回值的来判断handle()方法,到这里,然后回到最开始的地方

    //还记得这个循环吗,前面获取的
    while (!started && hasNextModelLoader()) {
          //现在我们已经知道这个list里的内容是什么了
          loadData = helper.getLoadData().get(loadDataListIndex++);
          //通过这里来判断loadData.fetcher.getDataSourc
          //其中loadData.fetcher就是我们factory.build()的返回值的buildLoadData()方法返回的内容
          if (loadData != null
              && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
                  || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
            started = true;
            loadData.fetcher.loadData(helper.getPriority(), this);
          }
        }
    

    根据helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource()这个判断,我们找到可用的就是下面这个

    .append(Uri.class, InputStream.class, new HttpUriLoader.Factory())
    

    来看这个factory

        public ModelLoader<Uri, InputStream> build(MultiModelLoaderFactory multiFactory) {
          //又来一遍,不过类型变成了GlideUrl.class, InputStream.class
          return new HttpUriLoader(multiFactory.build(GlideUrl.class, InputStream.class));
        }
    
      public HttpUriLoader(ModelLoader<GlideUrl, InputStream> urlLoader) {
        this.urlLoader = urlLoader;
      }
    
      @Override
      public LoadData<InputStream> buildLoadData(
          @NonNull Uri model, int width, int height, @NonNull Options options) {
        return urlLoader.buildLoadData(new GlideUrl(model.toString()), width, height, options);
      }
    
      @Override
      public boolean handles(@NonNull Uri model) {
        return SCHEMES.contains(model.getScheme());
      }
    

    又来一遍,但是类型变成了GlideUrl.class, InputStream.class,这个类型只有一个

    .append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
    

    继续看这个factory

        @NonNull
        @Override
        public ModelLoader<GlideUrl, InputStream> build(MultiModelLoaderFactory multiFactory) {
          return new HttpGlideUrlLoader(modelCache);
        }
    
      public HttpGlideUrlLoader(@Nullable ModelCache<GlideUrl, GlideUrl> modelCache) {
        this.modelCache = modelCache;
      }
    
      @Override
      public LoadData<InputStream> buildLoadData(
          @NonNull GlideUrl model, int width, int height, @NonNull Options options) {
        // GlideUrls memoize parsed URLs so caching them saves a few object instantiations and time
        // spent parsing urls.
        GlideUrl url = model;
        if (modelCache != null) {
          url = modelCache.get(model, 0, 0);
          if (url == null) {
            modelCache.put(model, 0, 0, model);
            url = model;
          }
        }
        int timeout = options.get(TIMEOUT);
        //最后会返回的是这里
        return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
      }
    
      @Override
      public boolean handles(@NonNull GlideUrl model) {
        return true;
      }
    

    所以loadData.fetcher.loadData(helper.getPriority(), this);中的fetcher就是上面的HttpUrlFetcher。

    相关文章

      网友评论

          本文标题:2019-11-19Glide 源码流程分析<1>

          本文链接:https://www.haomeiwen.com/subject/cmkwictx.html