Glide是Google 出的图片加载库,几乎是Android应用的标配了。对于它的用法和源码解析也是面试中经常问的。并且它的源码很复杂,也是一个原因之一

1. Glide 简单示例

  fun load(imgUrl:String ,target: ImageView) {
        Glide.with(target)
            .load(imgUrl)
            .into(target)
    }

这是一个load函数,虽然只有一行代码,却描述了Glide加载图片的过程中最少需要的三部分。这三部分分别对应with(),load(),into()三个方法。本文会根据这三部分来作源码分析。

2. Glide RequestManager的创建

with方法是一个静态方法返回值是RequestManager。具体看看with函数做了什么操作,这是一个重载方法,有几种不同的参数以构建RequestManager.

  public static RequestManager with(@NonNull View view) {
  // 1. getRetriver 会调用Glide.get(context).getRequestManagerRetriver() 
    return getRetriever(view.getContext()).get(view);
  }

可以看到这里是一个简单的方法,里面通过getRetriver()创建RequestManagerRetriver,然后通过get(view) 获取RequestManager.都这里也许疑问Glide类是否只是一个入口函数,没有glide对象?当然不是在getRetriver会对glide进行判断是否初始化,如果没有则新建glide 并赋值给Glide.glide静态成员。

 public static Glide get(@NonNull Context context) {
 // 单例模式
    if (glide == null) {
      GeneratedAppGlideModule annotationGeneratedModule =
          getAnnotationGeneratedGlideModules(context.getApplicationContext());
      synchronized (Glide.class) {
        if (glide == null) {
        // 进行glide 的创建
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }

    return glide;
  }

以下是对glide进行构建的方法,使用的是Builder模式

  private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    Context applicationContext = context.getApplicationContext();
    List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    // 1. 对AndroidManifest.xml 中的Glide Module 配置进行处理
    if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
      manifestModules = new ManifestParser(applicationContext).parse();
    }

    if (annotationGeneratedModule != null
        && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
      Set<Class<?>> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
      Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
      while (iterator.hasNext()) {
        com.bumptech.glide.module.GlideModule current = iterator.next();
        if (!excludedModuleClasses.contains(current.getClass())) {
          continue;
        }
。。。
        iterator.remove();
      }
    }

// 2. 构建RequstManagerFactory
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory()
            : null;
    // 3. factory 设置给Glide Builder
    builder.setRequestManagerFactory(factory);
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    // 4. 构建gilide,这一步包括设置requestManagerRetriver等成员初始化
    Glide glide = builder.build(applicationContext);
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      try {
        module.registerComponents(applicationContext, glide, glide.registry);
      } catch (AbstractMethodError e) {
        ...
      }
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
    }
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

Gilde.Builder build()方法

Glide build(@NonNull Context context) {
    if (sourceExecutor == null) {
    // 1. sourceExctor 线程池
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }

    if (diskCacheExecutor == null) {
    // 2. diskCache 线程池
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }

    if (animationExecutor == null) {
      animationExecutor = GlideExecutor.newAnimationExecutor();
    }

    if (memorySizeCalculator == null) {
      memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    }

    if (connectivityMonitorFactory == null) {
      connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }

// 3. bitmapPool
    if (bitmapPool == null) {
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
        bitmapPool = new LruBitmapPool(size);
      } else {
        bitmapPool = new BitmapPoolAdapter();
      }
    }

    if (arrayPool == null) {
      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }

    if (memoryCache == null) {
      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }

    if (diskCacheFactory == null) {
      diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    if (engine == null) {
    // 5. engine 创建
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }

    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }

    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    return new Glide(
        ...
  }

接着看RequestManagerRetriver是怎么获取RequestManager的get方法,这也是重载方法。一般情况会调用到在这里,从get(View)

  public RequestManager get(@NonNull Activity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      // 1. 重点在这里fragmentGet 为什么是fragment?
      return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }
  private RequestManager fragmentGet(
      @NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
      // 1. 这里创建了RequestManagerFragmet,这个Fragment 是创建出来绑定Glide的生命期的。
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
    // 2. 获取RequestManager
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      // TODO(b/27524013): Factor out this Glide.get() call.
      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

到这里RequestManager的创建分析的差不多了。接下来RequestManager是主要主角进行下一步了。

3. Glide 的加载,load

以加载一张网络图片为例,传入参数为string类型,会到以下源码。这里是通过RequestManager.load(),最终会到下面源码,返回一个RequestBuilder

public RequestBuilder<Drawable> load(@Nullable String string) {
    return asDrawable().load(string);
  }

可以看到会调用asDrawable() 然后返回RequestBuilder,跟进调用链,回到以下源码

  public <ResourceType> RequestBuilder<ResourceType> as(
      @NonNull Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
  }

可以看到new 了一个RequestBuilder对象,并且传入了resourceClass.接着看RequestBuilder的into()方法.into()方法有多个重载方法,用于把资源加载到target。这个target不一定是View。可以是各种ViewTarget。

4. Glide into()开始加载

  public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
 ...

    BaseRequestOptions<?> requestOptions = this;
    if (!requestOptions.isTransformationSet()
        && requestOptions.isTransformationAllowed()
        && view.getScaleType() != null) {
      // 通过veiw的scaleType 设置各种requestOptions
      switch (view.getScaleType()) {
        case CENTER_CROP:
          requestOptions = requestOptions.clone().optionalCenterCrop();
          break;
     ...
        default:
          // Do nothing.
      }
    }

    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        // 1. 回调线程
        Executors.mainThreadExecutor());
  }

最终执行的into方法

 private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
    Preconditions.checkNotNull(target);
   ...
   // 1. 构建Request
    Request request = buildRequest(target, targetListener, options, callbackExecutor);

    Request previous = target.getRequest();
    // 2. 判断是否target之前的request和当前的request相等
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
        // 3. 以下注释很好说明了下面代码的目的,如果previous 已经开始了,则使用previous
      // If the request is completed, beginning again will ensure the result is re-delivered,
      // triggering RequestListeners and Targets. If the request is failed, beginning again will
      // restart the request, giving it another chance to complete. If the request is already
      // running, we can let it continue running without interruption.
      if (!Preconditions.checkNotNull(previous).isRunning()) {
        // Use the previous request rather than the new one to allow for optimizations like skipping
        // setting placeholders, tracking and un-tracking Targets, and obtaining View dimensions
        // that are done in the individual Request.
        previous.begin();
      }
      return target;
    }

    requestManager.clear(target);
    // 4. target.setRequst
    target.setRequest(request);
    // 5. requestManager.track 真正开始网络请求的地方
    requestManager.track(target, request);

    return target;
  }

注释1.处的buildRequest也是很关键的一点,用于构建request

 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,
   ...) {

...

// 1. mainRequest 真正构建的request
    Request mainRequest =
        buildThumbnailRequestRecursive(
            requestLock,
            target,
            targetListener,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            requestOptions,
            callbackExecutor);

    if (errorRequestCoordinator == null) {
      return mainRequest;
    }

 ...
    Request errorRequest =
        errorBuilder.buildRequestRecursive(
            requestLock,
       ...t,
            errorBuilder,
            callbackExecutor);
    errorRequestCoordinator.setRequests(mainRequest, errorRequest);
    return errorRequestCoordinator;
  }
  

看一下ReqeustManager.track()方法是如何开始的。

 synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
  }

这是一个同步方法,继续跟可以看到到了RequestTracker

 public void runRequest(@NonNull Request request) {
 // 1. 正在执行的request
    requests.add(request);
    if (!isPaused) {
      request.begin();
    } else {
      request.clear();
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Paused, delaying request");
      }
      // 2. pending状态的request
      pendingRequests.add(request);
    }
  }

可以看到RequestTracker维护了了两个列表,requests,pendingRequests。

  private final List<Request> pendingRequests = new ArrayList<>();
private final Set<Request> requests =
      Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());

可以看到pendingReqeusts是强引用持有的,暂停状态的Request,会继续执行请求。requests是弱引用持有,当request取消了,或者生命周期执行完,取消请求,那么弱引用在gs时候会被释放。
runRequest执行了request.begain() ,request是一个interface .具体要看它的实现类。具体实现类实在RequestBuilder中的into()方法。后面回到buildThumbnailRequestRecursive()方法,最终执行到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);
  }

可以看到通过SingleRequest.obtain静态工厂方法返回的SingleRequest.接着看它的begain()方法。

  public void begin() {
    synchronized (requestLock) {
      assertNotCallingCallbacks();
      stateVerifier.throwIfRecycled();
      startTime = LogTime.getLogTime();
      if (model == null) {
        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
          width = overrideWidth;
          height = overrideHeight;
        }
      ...
        onLoadFailed(new GlideException("Received null model"), logLevel);
        return;
      }

      if (status == Status.RUNNING) {
        throw new IllegalArgumentException("Cannot restart a running request");
      }

      // If we're restarted after we're complete (usually via something like a notifyDataSetChanged
      // that starts an identical request into the same Target or View), we can simply use the
      // resource and size we retrieved the last time around and skip obtaining a new size, starting
      // a new load etc. This does mean that users who want to restart a load because they expect
      // that the view size has changed will need to explicitly clear the View or Target before
      // starting the new load.
      if (status == Status.COMPLETE) {
      // 1. 触发成功回调,为什么这里status == Status.COMPLETE 以上注释说得很清楚了
        onResourceReady(resource, DataSource.MEMORY_CACHE);
        return;
      }

      // Restarts for requests that are neither complete nor running can be treated as new requests
      // and can run again from the beginning.

      status = Status.WAITING_FOR_SIZE;
      if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      // 2. 执行请求的地方,核心代码
        onSizeReady(overrideWidth, overrideHeight);
      } else {
        target.getSize(this);
      }

      if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
          && canNotifyStatusChanged()) {
        target.onLoadStarted(getPlaceholderDrawable());
      }
    ...
    }
  }

SingleRequest的核心方法onSizeReady 执行了engine的load方法。

  public void onSizeReady(int width, int height) {
    stateVerifier.throwIfRecycled();
    synchronized (requestLock) {
   ...
      status = Status.RUNNING;

// 1. 确定宽高width ,height。是view真实的宽高,通过计算
      float sizeMultiplier = requestOptions.getSizeMultiplier();
      this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
      this.height = maybeApplySizeMultiplier(height, sizeMultiplier);

    ...
    // 2. 开始加载,并传入回调
      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方法中,传入了ResourceCallbac回调,作为资源加载后的通知。有个重要的回调方法onResourceReady会被调用。在这个方法又会调用targetListener的onResourceReady从而把返回的resource 设置到对应的target。

private void onResourceReady(Resource<R> resource, R result, DataSource dataSource) {
    ...

    isCallingCallbacks = true;
    try {
      boolean anyListenerHandledUpdatingTarget = false;
      if (requestListeners != null) {
        for (RequestListener<R> listener : requestListeners) {
          anyListenerHandledUpdatingTarget |=
              listener.onResourceReady(result, model, target, dataSource, isFirstResource);
        }
      }
      anyListenerHandledUpdatingTarget |=
          targetListener != null
              && targetListener.onResourceReady(result, model, target, dataSource, isFirstResource);

      if (!anyListenerHandledUpdatingTarget) {
        Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
        // 1. 把resulet 通知到target
        target.onResourceReady(result, animation);
      }
    } finally {
      isCallingCallbacks = false;
    }

    notifyLoadSuccess();
  }

接着看engine.load是如何执行的。这里涉及到glide的最关键之处了。其他部分都是调用流程。

  public <R> LoadStatus load(
      GlideContext glideContext,
      ...
      Executor callbackExecutor) {
    long startTime = VERBOSE_IS_LOGGABLE ? LogTime.getLogTime() : 0;

// 1. 生成EngineKey
    EngineKey key =
        keyFactory.buildKey(
            model,
            ...,
            transcodeClass,
            options);

    EngineResource<?> memoryResource;
    synchronized (this) {
    // 2. 从缓存总获取
      memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);

      if (memoryResource == null) {
      // 3. 如果缓存中没有则开始一个新的job去执行
        return waitForExistingOrStartNewJob(
            glideContext,
   ...
            key,
            startTime);
      }
    }

    // Avoid calling back while holding the engine lock, doing so makes it easier for callers to
    // deadlock.
    cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);
    return null;
  }

总体来说根据请求参数生成一个EngineKey,然后根据key获取缓存,缓存有则直接返回没有则调用waitForExistingAndStartNewJob()去请求。

private <R> LoadStatus waitForExistingOrStartNewJob(
      GlideContext glideContext,
      Object model,
   ...
      long startTime) {

    EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
    if (current != null) {
    // 1.判断jobs 是否已有当前job
      current.addCallback(cb, callbackExecutor);
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Added to existing load", startTime, key);
      }
      return new LoadStatus(cb, current);
    }

// 2. 创建一个engineJob
    EngineJob<R> engineJob =
        engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);

// 3. 创建一个decodeJob
    DecodeJob<R> decodeJob =
        decodeJobFactory.build(
            glideContext,
            model,
            key,
           ...
           rieveFromCache,
            options,
            engineJob);

// 4. enjineJob添加到jobs中
    jobs.put(key, engineJob);

    engineJob.addCallback(cb, callbackExecutor);
    // 5. start enjinbJob
    engineJob.start(decodeJob);

    if (VERBOSE_IS_LOGGABLE) {
      logWithTimeAndKey("Started new load", startTime, key);
    }
    return new LoadStatus(cb, engineJob);
  }

可以看到enineJob start 开始执行任务。

 public synchronized void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    GlideExecutor executor =
        decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
    executor.execute(decodeJob);
  }

很简单的代码,主要逻辑在decodeJob了。在decodeJob中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);
    }
  }

runWrpped根据runReason 执行不同的加载策越。主要方法是runGenerators().

 private void runGenerators() {
    currentThread = Thread.currentThread();
    startFetchTime = LogTime.getLogTime();
    boolean isStarted = false;
    // 1. 关键在于这里通过while循环,不断的通过getNextGenerator()给currentGenerator赋值,然后调用startNex()方法。
    while (!isCancelled
        && currentGenerator != null
        && !(isStarted = currentGenerator.startNext())) {
      stage = getNextStage(stage);
      currentGenerator = getNextGenerator();

      if (stage == Stage.SOURCE) {
        reschedule();
        return;
      }
    }
  ...
...
  }
  private DataFetcherGenerator getNextGenerator() {
    switch (stage) {
      case RESOURCE_CACHE:
        return new ResourceCacheGenerator(decodeHelper, this);
      case DATA_CACHE:
        return new DataCacheGenerator(decodeHelper, this);
      case SOURCE:
        return new SourceGenerator(decodeHelper, this);
      case FINISHED:
        return null;
      default:
        throw new IllegalStateException("Unrecognized stage: " + stage);
    }
  }

getNextGenerator 根据不同的stage返回不同的DataFetcherGenerator。这里我们看state == SOURCE 返回的SourceGenerator执行的方法。

  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
    // 1. 会循环hasNextModelLoader(),对每一个loadDat执行startNextLoade(loadData)
    while (!started && hasNextModelLoader()) {
      loadData = helper.getLoadData().get(loadDataListIndex++);
      if (loadData != null
          && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
              || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
        started = true;
        startNextLoad(loadData);
      }
    }
    return started;
  }
  private void startNextLoad(final LoadData<?> toStart) {
    loadData.fetcher.loadData(
        helper.getPriority(),
        new DataCallback<Object>() {
          @Override
          public void onDataReady(@Nullable Object data) {
            if (isCurrentRequest(toStart)) {
              onDataReadyInternal(toStart, data);
            }
          }

          @Override
          public void onLoadFailed(@NonNull Exception e) {
            if (isCurrentRequest(toStart)) {
              onLoadFailedInternal(toStart, e);
            }
          }
        });
  }

可以看到关键的对方在于loadData.fetcher。这是哪里赋值的?可以看到是helper.getLoadData()得到的List中根据下表获取的,在DecodeJob中可以看到是通过直接new DecodeHelper()对helper初始化的

  private final DecodeHelper<R> decodeHelper = new DecodeHelper<>();

 List<LoadData<?>> getLoadData() {
    if (!isLoadDataSet) {
      isLoadDataSet = true;
      loadData.clear();
      // 1. 通过glideCOntext 获取所有ModelLoaders
      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);
        LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
        if (current != null) {
          loadData.add(current);
        }
      }
    }
    return loadData;
  }

关键的执行请求的逻辑也就是在ModelLoader的fetcher中,那么这些ModelLoader事在哪里赋值的呢,在glideContext 自然是在Glide初始化就已经执行了的。从这里可以看到glide 是模块化的,之前loadData的操作可以自己自定义。我们看默认的ModelLoader实现是怎样的。在glide的构造方法中看到这样一段代码

 registry
        .append(Uri.class, InputStream.class, new UriLoader.StreamFactory(contentResolver))
        .append(
            Uri.class,
            ParcelFileDescriptor.class,
            new UriLoader.FileDescriptorFactory(contentResolver))
        .append(
            Uri.class,
            AssetFileDescriptor.class,
            new UriLoader.AssetFileDescriptorFactory(contentResolver))
        .append(Uri.class, InputStream.class, new UrlUriLoader.StreamFactory())
        .append(URL.class, InputStream.class, new UrlLoader.StreamFactory())
        .append(Uri.class, File.class, new MediaStoreFileLoader.Factory(context))
        .append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
        .append(byte[].class, ByteBuffer.class, new ByteArrayLoader.ByteBufferFactory())
        .append(byte[].class, InputStream.class, new ByteArrayLoader.StreamFactory())
        .append(Uri.class, Uri.class, UnitModelLoader.Factory.<Uri>getInstance())
        .append(Drawable.class, Drawable.class, UnitModelLoader.Factory.<Drawable>getInstance())
        .append(Drawable.class, Drawable.class, new UnitDrawableDecoder())

这里就是通过registry添加各种ModelLoader的地方。我们找一个UnitModelLoader看一下。可以看到在它的buildLoadData

 public LoadData<Model> buildLoadData(
      @NonNull Model model, int width, int height, @NonNull Options options) {
    return new LoadData<>(new ObjectKey(model), new UnitFetcher<>(model));
  }

它的fetcher是UnitFetcher。这些各种ModelLoader处理各种Resource类型的请求,比如Drawable,Uri等。如果我们只是简单的网络图片呢,则执行HttpGlideUrlLoader。这里我们看一下代码

 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));
  }

返回的是HttpUrlFetcher.

  public void loadData(
      @NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
    long startTime = LogTime.getLogTime();
    try {
      InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
      callback.onDataReady(result);
    }...
      callback.onLoadFailed(e);
    ...
    }
  }
  private InputStream loadDataWithRedirects(
      URL url, int redirects, URL lastUrl, Map<String, String> headers) throws IOException {
    if (redirects >= MAXIMUM_REDIRECTS) {
  ....
    1. 构建一个urlConnection
    urlConnection = connectionFactory.build(url);
    ...
    avoid errors in decoders if connection fails.
    urlConnection.connect();
    // Set the stream so that it's closed in cleanup to avoid resource leaks. See #2352.
    stream = urlConnection.getInputStream();
    if (isCancelled) {
      return null;
    }
   ...
      return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
    } else if (statusCode == INVALID_STATUS_CODE) {
      throw new HttpException(statusCode);
    } else {
      throw new HttpException(urlConnection.getResponseMessage(), statusCode);
    }
  }

在这里最终通过loadDataWithRRedirects了inputStream.并执行了onResourceReady回调。支持Glie完整流程的请求已经分析完毕。接下来需要对获取到的resource 进行更深入的处理,比如缓存和转换等。还记得在DecodeJob的getNextGenerator方法吗?在哪里有三种Generator分别是ResourceCacheGenerator,DataCacheGenerator,SourceGenerator.看名字我们大概可以明白前两个跟缓存有关。并且这两个类也是要执行到DecodeHelper 里面的ModelerLoader。

5. Glide的缓存机制


在Engine的load方法中可以看到调用了loadFromMemory

1. 从activeResources 中获取,这是弱引用持有,当lrucache 队列已满时移除,然后把resource 存入activeResource
  EngineResource<?> active = loadFromActiveResources(key);
    if (active != null) {
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from active resources", startTime, key);
      }
      return active;
    }
// 2. 缓存中获取 LruCache
    EngineResource<?> cached = loadFromCache(key);
  private EngineResource<?> loadFromCache(Key key) {
    EngineResource<?> cached = getEngineResourceFromCache(key);
    if (cached != null) {
      cached.acquire();
      // 从缓存中获取之后,移除Lrucache 然后添加到activeResources
      activeResources.activate(key, cached);
    }
    return cached;
  }

参考资料