Glide 源码浅析

这里只分析一下最简单的流程,以下是使用示例:

Glide.with(getApplicationContext()).load(url)
    .into(ImageView view);

源码分析

以上就是一个简单的流程了, 我们先看一下 Glide.with(Context context)

Glide.with(Context context)
@NonNull
public static RequestManager with(@NonNull Context context) {
    /* 分为两步,
        1 创建 RequestManagerRetriver 
        2 创建 RequestManager
    */
    return getRetriever(context).get(context);
}

第一步 getRetriver(Context context)

private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    // 实际上是先创建 Glide 实例, 然后返回了它的成员变量
    return Glide.get(context).getRequestManagerRetriever();
}

public static Glide get(@NonNull Context context) {
  if (glide == null) {
    GeneratedAppGlideModule annotationGeneratedModule =
        getAnnotationGeneratedGlideModules(context.getApplicationContext());
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context, annotationGeneratedModule);
      }
    }
  }
  return glide;
}

private static void checkAndInitializeGlide(
    @NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
  // In the thread running initGlide(), one or more classes may call Glide.get(context).
  // Without this check, those calls could trigger infinite recursion.
  if (isInitializing) {
    throw new IllegalStateException(
        "You cannot call Glide.get() in registerComponents(),"
            + " use the provided Glide instance instead");
  }
  isInitializing = true;
  initializeGlide(context, generatedAppGlideModule);
  isInitializing = false;
}
private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory()
            : null;
    builder.setRequestManagerFactory(factory);

    // 通过建造着模式创建 Glide
    Glide glide = builder.build(applicationContext);

    Glide.glide = glide;
}

public final class GlideBuilder {
      Glide build(@NonNull Context context) {
            // 一些用来做请求,缓存的线程池创建
            if (sourceExecutor == null) {
              sourceExecutor = GlideExecutor.newSourceExecutor();
            }
        
            if (diskCacheExecutor == null) {
              diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
            }
        
            if (animationExecutor == null) {
              animationExecutor = GlideExecutor.newAnimationExecutor();
            }
            // 计算缓存的内存大小 
            if (memorySizeCalculator == null) {
              memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
            }
        
            if (connectivityMonitorFactory == null) {
              connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
            }
        
            if (bitmapPool == null) {
              int size = memorySizeCalculator.getBitmapPoolSize();
              if (size > 0) {
                // Lru 策略的缓存池
                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);
            }
            // 创建 Engine 类, 获取资源实际通过 Engine 类来进行
            if (engine == null) {
              engine =
                  new Engine(
                      memoryCache,
                      diskCacheFactory,
                      diskCacheExecutor,
                      sourceExecutor,
                      GlideExecutor.newUnlimitedSourceExecutor(),
                      animationExecutor,
                      isActiveResourceRetentionAllowed);
            }
        
            if (defaultRequestListeners == null) {
              defaultRequestListeners = Collections.emptyList();
            } else {
              defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
            }
            // 生成 RequestManagerRetriver 属性, 这里 factory 实际为 null
            // 构造方法中采用一个默认的 Factory
            RequestManagerRetriever requestManagerRetriever =
                new RequestManagerRetriever(requestManagerFactory);
            // 真正的创建 Glide
            return new Glide(
                context,
                engine,
                memoryCache,
                bitmapPool,
                arrayPool,
                requestManagerRetriever,
                connectivityMonitorFactory,
                logLevel,
                defaultRequestOptionsFactory,
                defaultTransitionOptions,
                defaultRequestListeners,
                isLoggingRequestOriginsEnabled,
                isImageDecoderEnabledForBitmaps);
              }
}

Glide 的构造函数

// 构造函数里比较重要的就是 Registry 它对你后续理解资源的加载至关重要
// 里面将需要加在的资源类型,数据类型, 生成加载类的 Factory 对应起来存储 
Glide(
    @NonNull Context context,
    @NonNull Engine engine,
    @NonNull MemoryCache memoryCache,
    @NonNull BitmapPool bitmapPool,
    @NonNull ArrayPool arrayPool,
    @NonNull RequestManagerRetriever requestManagerRetriever,
    @NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
    int logLevel,
    @NonNull RequestOptionsFactory defaultRequestOptionsFactory,
    @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
    @NonNull List<RequestListener<Object>> defaultRequestListeners,
    boolean isLoggingRequestOriginsEnabled,
    boolean isImageDecoderEnabledForBitmaps) {
    this.engine = engine;
    this.bitmapPool = bitmapPool;
    this.arrayPool = arrayPool;
    this.memoryCache = memoryCache;
    this.requestManagerRetriever = requestManagerRetriever;
    this.connectivityMonitorFactory = connectivityMonitorFactory;
    this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;

    final Resources resources = context.getResources();

    registry = new Registry();
    registry.register(new DefaultImageHeaderParser());
    // Right now we're only using this parser for HEIF images, which are only supported on OMR1+.
    // If we need this for other file types, we should consider removing this restriction.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        registry.register(new ExifInterfaceImageHeaderParser());
    }

    List<ImageHeaderParser> imageHeaderParsers = registry.getImageHeaderParsers();

    ByteBufferGifDecoder byteBufferGifDecoder =
    new ByteBufferGifDecoder(context, imageHeaderParsers, bitmapPool, arrayPool);
    ResourceDecoder<ParcelFileDescriptor, Bitmap> parcelFileDescriptorVideoDecoder =
    VideoDecoder.parcel(bitmapPool);

    // TODO(judds): Make ParcelFileDescriptorBitmapDecoder work with ImageDecoder.
    Downsampler downsampler =
    new Downsampler(
        registry.getImageHeaderParsers(), resources.getDisplayMetrics(), bitmapPool, arrayPool);

    ResourceDecoder<ByteBuffer, Bitmap> byteBufferBitmapDecoder;
    ResourceDecoder<InputStream, Bitmap> streamBitmapDecoder;
    if (isImageDecoderEnabledForBitmaps && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        streamBitmapDecoder = new InputStreamBitmapImageDecoderResourceDecoder();
        byteBufferBitmapDecoder = new ByteBufferBitmapImageDecoderResourceDecoder();
    } else {
        byteBufferBitmapDecoder = new ByteBufferBitmapDecoder(downsampler);
        streamBitmapDecoder = new StreamBitmapDecoder(downsampler, arrayPool);
    }

    ResourceDrawableDecoder resourceDrawableDecoder = new ResourceDrawableDecoder(context);
    ResourceLoader.StreamFactory resourceLoaderStreamFactory =
    new ResourceLoader.StreamFactory(resources);
    ResourceLoader.UriFactory resourceLoaderUriFactory = new ResourceLoader.UriFactory(resources);
    ResourceLoader.FileDescriptorFactory resourceLoaderFileDescriptorFactory =
    new ResourceLoader.FileDescriptorFactory(resources);
    ResourceLoader.AssetFileDescriptorFactory resourceLoaderAssetFileDescriptorFactory =
      new ResourceLoader.AssetFileDescriptorFactory(resources);
  BitmapEncoder bitmapEncoder = new BitmapEncoder(arrayPool);

  BitmapBytesTranscoder bitmapBytesTranscoder = new BitmapBytesTranscoder();
  GifDrawableBytesTranscoder gifDrawableBytesTranscoder = new GifDrawableBytesTranscoder();

  ContentResolver contentResolver = context.getContentResolver();

  registry
      .append(ByteBuffer.class, new ByteBufferEncoder())
      .append(InputStream.class, new StreamEncoder(arrayPool))
      /* Bitmaps */
      .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
      .append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder);

  if (ParcelFileDescriptorRewinder.isSupported()) {
    registry.append(
        Registry.BUCKET_BITMAP,
        ParcelFileDescriptor.class,
        Bitmap.class,
        new ParcelFileDescriptorBitmapDecoder(downsampler));
  }

  registry
      .append(
          Registry.BUCKET_BITMAP,
          ParcelFileDescriptor.class,
          Bitmap.class,
          parcelFileDescriptorVideoDecoder)
      .append(
          Registry.BUCKET_BITMAP,
          AssetFileDescriptor.class,
          Bitmap.class,
          VideoDecoder.asset(bitmapPool))
      .append(Bitmap.class, Bitmap.class, UnitModelLoader.Factory.<Bitmap>getInstance())
      .append(Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder())
      .append(Bitmap.class, bitmapEncoder)
      /* BitmapDrawables */
      .append(
          Registry.BUCKET_BITMAP_DRAWABLE,
          ByteBuffer.class,
          BitmapDrawable.class,
          new BitmapDrawableDecoder<>(resources, byteBufferBitmapDecoder))
      .append(
          Registry.BUCKET_BITMAP_DRAWABLE,
          InputStream.class,
          BitmapDrawable.class,
          new BitmapDrawableDecoder<>(resources, streamBitmapDecoder))
      .append(
          Registry.BUCKET_BITMAP_DRAWABLE,
          ParcelFileDescriptor.class,
          BitmapDrawable.class,
          new BitmapDrawableDecoder<>(resources, parcelFileDescriptorVideoDecoder))
      .append(BitmapDrawable.class, new BitmapDrawableEncoder(bitmapPool, bitmapEncoder))
      /* GIFs */
      .append(
          Registry.BUCKET_GIF,
          InputStream.class,
          GifDrawable.class,
          new StreamGifDecoder(imageHeaderParsers, byteBufferGifDecoder, arrayPool))
      .append(Registry.BUCKET_GIF, ByteBuffer.class, GifDrawable.class, byteBufferGifDecoder)
      .append(GifDrawable.class, new GifDrawableEncoder())
      /* GIF Frames */
      // Compilation with Gradle requires the type to be specified for UnitModelLoader here.
      .append(
          GifDecoder.class, GifDecoder.class, UnitModelLoader.Factory.<GifDecoder>getInstance())
      .append(
          Registry.BUCKET_BITMAP,
          GifDecoder.class,
          Bitmap.class,
          new GifFrameResourceDecoder(bitmapPool))
      /* Drawables */
      .append(Uri.class, Drawable.class, resourceDrawableDecoder)
      .append(
          Uri.class, Bitmap.class, new ResourceBitmapDecoder(resourceDrawableDecoder, bitmapPool))
      /* Files */
      .register(new ByteBufferRewinder.Factory())
      .append(File.class, ByteBuffer.class, new ByteBufferFileLoader.Factory())
      .append(File.class, InputStream.class, new FileLoader.StreamFactory())
      .append(File.class, File.class, new FileDecoder())
      .append(File.class, ParcelFileDescriptor.class, new FileLoader.FileDescriptorFactory())
      // Compilation with Gradle requires the type to be specified for UnitModelLoader here.
      .append(File.class, File.class, UnitModelLoader.Factory.<File>getInstance())
      /* Models */
      .register(new InputStreamRewinder.Factory(arrayPool));

  if (ParcelFileDescriptorRewinder.isSupported()) {
    registry.register(new ParcelFileDescriptorRewinder.Factory());
  }

  registry
      .append(int.class, InputStream.class, resourceLoaderStreamFactory)
      .append(int.class, ParcelFileDescriptor.class, resourceLoaderFileDescriptorFactory)
      .append(Integer.class, InputStream.class, resourceLoaderStreamFactory)
      .append(Integer.class, ParcelFileDescriptor.class, resourceLoaderFileDescriptorFactory)
      .append(Integer.class, Uri.class, resourceLoaderUriFactory)
      .append(int.class, AssetFileDescriptor.class, resourceLoaderAssetFileDescriptorFactory)
      .append(Integer.class, AssetFileDescriptor.class, resourceLoaderAssetFileDescriptorFactory)
      .append(int.class, Uri.class, resourceLoaderUriFactory)
      .append(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())
      .append(Uri.class, InputStream.class, new DataUrlLoader.StreamFactory<Uri>())
      .append(String.class, InputStream.class, new StringLoader.StreamFactory())
      .append(String.class, ParcelFileDescriptor.class, new StringLoader.FileDescriptorFactory())
      .append(
          String.class, AssetFileDescriptor.class, new StringLoader.AssetFileDescriptorFactory())
      .append(Uri.class, InputStream.class, new HttpUriLoader.Factory())
      .append(Uri.class, InputStream.class, new AssetUriLoader.StreamFactory(context.getAssets()))
      .append(
          Uri.class,
          ParcelFileDescriptor.class,
          new AssetUriLoader.FileDescriptorFactory(context.getAssets()))
      .append(Uri.class, InputStream.class, new MediaStoreImageThumbLoader.Factory(context))
      .append(Uri.class, InputStream.class, new MediaStoreVideoThumbLoader.Factory(context));
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    registry.append(
        Uri.class, InputStream.class, new QMediaStoreUriLoader.InputStreamFactory(context));
    registry.append(
        Uri.class,
        ParcelFileDescriptor.class,
        new QMediaStoreUriLoader.FileDescriptorFactory(context));
  }
  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())
      /* Transcoders */
      .register(Bitmap.class, BitmapDrawable.class, new BitmapDrawableTranscoder(resources))
      .register(Bitmap.class, byte[].class, bitmapBytesTranscoder)
      .register(
          Drawable.class,
          byte[].class,
          new DrawableBytesTranscoder(
              bitmapPool, bitmapBytesTranscoder, gifDrawableBytesTranscoder))
      .register(GifDrawable.class, byte[].class, gifDrawableBytesTranscoder);

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    ResourceDecoder<ByteBuffer, Bitmap> byteBufferVideoDecoder =
        VideoDecoder.byteBuffer(bitmapPool);
    registry.append(ByteBuffer.class, Bitmap.class, byteBufferVideoDecoder);
    registry.append(
        ByteBuffer.class,
        BitmapDrawable.class,
        new BitmapDrawableDecoder<>(resources, byteBufferVideoDecoder));
  }

  ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
  glideContext =
      new GlideContext(
          context,
          arrayPool,
          registry,
          imageViewTargetFactory,
          defaultRequestOptionsFactory,
          defaultTransitionOptions,
          defaultRequestListeners,
          engine,
          isLoggingRequestOriginsEnabled,
          logLevel);
}

第二步 获取 RequestManager

RequestManagerRetriver.get(Context context)

public RequestManager get(@NonNull Context context) {
    if (context == null) {
        throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
        if (context instanceof FragmentActivity) {
            // 生命周期管理
            return get((FragmentActivity) context);
        } else if (context instanceof Activity) {
            return get((Activity) context);
        } else if (context instanceof ContextWrapper
                   // Only unwrap a ContextWrapper if the baseContext has a non-null application context.
                   // Context#createPackageContext may return a Context without an Application instance,
                   // in which case a ContextWrapper may be used to attach one.
                   && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
            return get(((ContextWrapper) context).getBaseContext());
        }
    }
    
    return getApplicationManager(context);
}

// 直接通过 Factory 创建了一个 RequestManager, 不指定的话, 这个 Factory 是 ReqeustManagerRetriver 中的
// DEFAULT_FACTORY
  private RequestManager getApplicationManager(@NonNull Context context) {
    // Either an application context or we're on a background thread.
    if (applicationManager == null) {
      synchronized (this) {
        if (applicationManager == null) {
          // Normally pause/resume is taken care of by the fragment we add to the fragment or
          // activity. However, in this case since the manager attached to the application will not
          // receive lifecycle events, we must force the manager to start resumed using
          // ApplicationLifecycle.

          // TODO(b/27524013): Factor out this Glide.get() call.
          Glide glide = Glide.get(context.getApplicationContext());
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }

    return applicationManager;
  }

这里需要注意的是 Glide 的声明周期的管理, 是通过上图中声明周期管理注释处的代码来实现的。

生命周期管理

以 FragmentActivity 为例

@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
        // 如果是后台的线程,直接与 Application 关联
        return get(activity.getApplicationContext());
    } else {
        assertNotDestroyed(activity);
        // 通过 FragmentManager 创建一个 Fragment
        FragmentManager fm = activity.getSupportFragmentManager();
        return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
}


private RequestManager supportFragmentGet(
    @NonNull Context context,
    @NonNull FragmentManager fm,
    @Nullable Fragment parentHint,
    boolean isParentVisible) {
  // 创建一个与 Activity 关联的 SupportRequestManagerFragment
  SupportRequestManagerFragment current =
      getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
  RequestManager requestManager = current.getRequestManager();
  if (requestManager == null) {
    // TODO(b/27524013): Factor out this Glide.get() call.
    Glide glide = Glide.get(context);
    // 将这个 Fragment 的生命周期监听钩子(LifieCycle) 交给 RequestManager
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    current.setRequestManager(requestManager);
  }
  return requestManager;
}

@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
    @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
  // 先通过 fm 获取
  SupportRequestManagerFragment current =
      (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
  if (current == null) {
    // 通过 Map 的内存缓存获取
    current = pendingSupportRequestManagerFragments.get(fm);
    if (current == null) {
      // 获取不到再 new
      current = new SupportRequestManagerFragment();
      current.setParentFragmentHint(parentHint);
      if (isParentVisible) {
        current.getGlideLifecycle().onStart();
      }
      // 然后放入到 Map 中缓存
      pendingSupportRequestManagerFragments.put(fm, current);
      // 将 Fragment 与 Activity 的声明周期关联
      fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
      // 发送消息移除 Map 中的缓存
      handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
    }
  }
  return current;
}

RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    // ...
    this.lifecycle = lifecycle;
    // ...
    // 在这里关联的 lifecycle 生命周期变化时会回调 RequestManager , 从而管理 
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

    defaultRequestListeners =
        new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

    glide.registerRequestManager(this);
  }

总结起来就是,通过 创建一个 Fragment 与传入的 Activity 声明周期相关联,通过监听 Fragment 的生命周期, 来进行声明周期的一个管理。

RequestManager.load(String url)
// load 方法比较简单
public RequestBuilder<Drawable> load(@Nullable String string) {
    return asDrawable().load(string);
}

public RequestBuilder<Drawable> asDrawable() {
  return as(Drawable.class);
}

// asDrawable 创建了一个 RequestBuilder ,并且传入的 resourceClass 为 Drawable.Class
public <ResourceType> RequestBuilder<ResourceType> as(
    @NonNull Class<ResourceType> resourceClass) {
  return new RequestBuilder<>(glide, this, resourceClass, context);
}

public RequestBuilder<TranscodeType> load(@Nullable String string) {
  return loadGeneric(string);
}
// load 方法则保存了一下,同时设置了一个状态位
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
  this.model = model;
  isModelSet = true;
  return this;
}

所以比较关键的方法在于 into 方法

RequestBuilder.into(ImageView view)
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    Util.assertMainThread();
    // ...
    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        Executors.mainThreadExecutor());
}

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 request = buildRequest(target, targetListener, options, callbackExecutor);

    // 这里没有前一个,这段逻辑可以忽略
    Request previous = target.getRequest();
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, 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;
    }
    // 执行 Request
    requestManager.clear(target);
    target.setRequest(request);
    requestManager.track(target, request);

    return target;
  }

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,
    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;
  if (errorBuilder != null) {
    errorRequestCoordinator = new ErrorRequestCoordinator(requestLock, parentCoordinator);
    parentCoordinator = errorRequestCoordinator;
  }
  Request mainRequest =
      buildThumbnailRequestRecursive(
          requestLock,
          target,
          targetListener,
          parentCoordinator,
          transitionOptions,
          priority,
          overrideWidth,
          overrideHeight,
          requestOptions,
          callbackExecutor);
  // 如果不需要处理错误逻辑,就返回 mainRequest 
  if (errorRequestCoordinator == null) {
    return mainRequest;
  }
  int errorOverrideWidth = errorBuilder.getOverrideWidth();
  int errorOverrideHeight = errorBuilder.getOverrideHeight();
  if (Util.isValidDimensions(overrideWidth, overrideHeight) && !errorBuilder.isValidOverride()) {
    errorOverrideWidth = requestOptions.getOverrideWidth();
    errorOverrideHeight = requestOptions.getOverrideHeight();
  }
  Request errorRequest =
      errorBuilder.buildRequestRecursive(
          requestLock,
          target,
          targetListener,
          errorRequestCoordinator,
          errorBuilder.transitionOptions,
          errorBuilder.getPriority(),
          errorOverrideWidth,
          errorOverrideHeight,
          errorBuilder,
          callbackExecutor);
  errorRequestCoordinator.setRequests(mainRequest, errorRequest);
  return errorRequestCoordinator;
}

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);
  }
}
// 最后得到了一个 SingleRequest 对象
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);
}

RequestManager.track( Target<?> target, Request request)

synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
    // 将  Target 放入到 Set 集合中
    targetTracker.track(target);
    // 执行 Request
    requestTracker.runRequest(request);
}

public final class TargetTracker implements LifecycleListener { 
  public void track(@NonNull Target<?> target) {
    targets.add(target);
  }
}

public class RequestTracker { 
  public void runRequest(@NonNull Request request) {
    requests.add(request);
    if (!isPaused) {
      // 状态正确时, 开始执行 Request
      request.begin();
    } else {
      request.clear();
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Paused, delaying request");
      }
      pendingRequests.add(request);
    }
  }
}

这里的 Request 通过前面的分析,为 SingleRequest 对象

第一步是获取加载目标的大小

public void begin() {
    synchronized (requestLock) {

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

        // 第一步先加载需要展示的图片的大小, 这里就是 into 的对象的大小
        status = Status.WAITING_FOR_SIZE;
        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
            onSizeReady(overrideWidth, overrideHeight);
        } else {
            // 初次进入 overrideWidth、overrideHeight 是没有赋值的
            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 回调

第二步开始加载资源
public void onSizeReady(int width, int height) {
    stateVerifier.throwIfRecycled();
    synchronized (requestLock) {
        // ...
        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));
        }
        // 通过 Engine 开始加载资源
        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);

        // This is a hack that's only useful for testing right now where loads complete synchronously
        // even though under any executor running on any thread but the main thread, the load would
        // have completed asynchronously.
        if (status != Status.RUNNING) {
            loadStatus = null;
        }
        if (IS_VERBOSE_LOGGABLE) {
            logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
        }
    }
}

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;

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

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

首先从缓存中加载资源, 看是否已经存在

private EngineResource<?> loadFromMemory(
    EngineKey key, boolean isMemoryCacheable, long startTime) {
    if (!isMemoryCacheable) {
        return null;
    }
    // 首先从内存中加载 activeResources 中的 Map 集合
    EngineResource<?> active = loadFromActiveResources(key);
    if (active != null) {
        if (VERBOSE_IS_LOGGABLE) {
            logWithTimeAndKey("Loaded resource from active resources", startTime, key);
        }
        return active;
    }

    // 然后从 MemoryCache 中获取, 获取到的话加入到 ActiveResources 中
    // 实际就是 LruCache
    EngineResource<?> cached = loadFromCache(key);
    if (cached != null) {
        if (VERBOSE_IS_LOGGABLE) {
            logWithTimeAndKey("Loaded resource from cache", startTime, key);
        }
        return cached;
    }

    return null;
}

从这个函数来看的话,有两种缓存机制, 一种是 HashMap 内存缓存, 还有一种是 LruCache 实现的内存缓存。 实际上, Glide 还有一种缓存机制,磁盘缓存 , 通过 DiskLruCache 来实现, 磁盘缓存会在接下来的分析过程中讲到。

如果没有从内存加载到数据, 则开始网路加载流程

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);
    }
    // 没有再通过 Factory 创建
    // 创建 EngineJob
    EngineJob<R> engineJob =
    engineJobFactory.build(
        key,
        isMemoryCacheable,
        useUnlimitedSourceExecutorPool,
        useAnimationPool,
        onlyRetrieveFromCache);

    // 创建 DecodeJob , 加载任务其实再 DecodeJob 来执行
    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 作为总管来执行 decodeJob
    engineJob.addCallback(cb, callbackExecutor);
    engineJob.start(decodeJob);

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

// EngineJob 的  start 方法
public synchronized void start(DecodeJob<R> decodeJob) {
  this.decodeJob = decodeJob;
    // 先获取线程池, 区分是磁盘缓存获取还是直接网络请求
  GlideExecutor executor =
      decodeJob.willDecodeFromCache() ? diskCacheExecutor : getActiveSourceExecutor();
  // 执行 decodeJob
  executor.execute(decodeJob);
}

线程池会执行到 DecodeJob 的 run 方法

public void run() {

    // Methods in the try statement can invalidate currentFetcher, so set a local variable here to
    // ensure that the fetcher is cleaned up either way.
    DataFetcher<?> localFetcher = currentFetcher;
    try {
        if (isCancelled) {
            notifyFailed();
            return;
        }
        // 真正执行的是 runWrapped
        runWrapped();
    } catch (CallbackException e) {
        // If a callback not controlled by Glide throws an exception, we should avoid the Glide
        // specific debug logic below.
        throw e;
    } catch (Throwable t) {
        // Catch Throwable and not Exception to handle OOMs. Throwables are swallowed by our
        // usage of .submit() in GlideExecutor so we're not silently hiding crashes by doing this. We
        // are however ensuring that our callbacks are always notified when a load fails. Without this
        // notification, uncaught throwables never notify the corresponding callbacks, which can cause
        // loads to silently hang forever, a case that's especially bad for users using Futures on
        // background threads.
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(
                TAG,
                "DecodeJob threw unexpectedly" + ", isCancelled: " + isCancelled + ", stage: " + stage,
                t);
        }
        // When we're encoding we've already notified our callback and it isn't safe to do so again.
        if (stage != Stage.ENCODE) {
            throwables.add(t);
            notifyFailed();
        }
        if (!isCancelled) {
            throw t;
        }
        throw t;
    } finally {
        // Keeping track of the fetcher here and calling cleanup is excessively paranoid, we call
        // close in all cases anyway.
        if (localFetcher != null) {
            localFetcher.cleanup();
        }
        GlideTrace.endSection();
    }
}

private void runWrapped() {
  // 初始化为 INITIALIZE
  switch (runReason) {
    case INITIALIZE:
      // 获取到下一步该执行的状态 SOURCE
      stage = getNextStage(Stage.INITIALIZE);
      // 根据状态获取到 SourceGenerator
      currentGenerator = getNextGenerator();
      // 执行 Generator
      runGenerators();
      break;
    case SWITCH_TO_SOURCE_SERVICE:
      runGenerators();
      break;
    case DECODE_DATA:
      decodeFromRetrievedData();
      break;
    default:
      throw new IllegalStateException("Unrecognized run reason: " + runReason);
  }
}

private Stage getNextStage(Stage current) {
    switch (current) {
      // 如果采用缓存, 则返回 RESOUCE_CACHE 执行 cache 加载流程
      // 如果不用缓存, 则跳过缓存流程,直接返回 SOURCE 执行 source 加载流程
      case INITIALIZE:
        return diskCacheStrategy.decodeCachedResource()
            ? Stage.RESOURCE_CACHE
            : getNextStage(Stage.RESOURCE_CACHE);
      case RESOURCE_CACHE:
        return diskCacheStrategy.decodeCachedData()
            ? Stage.DATA_CACHE
            : getNextStage(Stage.DATA_CACHE);
      case DATA_CACHE:
        // Skip loading from source if the user opted to only retrieve the resource from cache.
        return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
      case SOURCE:
      case FINISHED:
        return Stage.FINISHED;
      default:
        throw new IllegalArgumentException("Unrecognized stage: " + current);
    }
  }
// source 状态 直接返回 SourceGenerator
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);
  }
}

private void runGenerators() {
  currentThread = Thread.currentThread();
  startFetchTime = LogTime.getLogTime();
  boolean isStarted = false;
  while (!isCancelled
      && currentGenerator != null
      //  执行了 Generator 的 startNext 方法
      && !(isStarted = currentGenerator.startNext())) {
     // SOURCE 的下一阶段为 FINISH  表示执行完了
    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();
  }

所以主要的流程就在 Generator 的 startNext 方法中。

class SourceGenerator implements DataFetcherGenerator, DataFetcherGenerator.FetcherReadyCallback {
  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;
    // 执行这个流程
    while (!started && hasNextModelLoader()) {
      loadData = helper.getLoadData().get(loadDataListIndex++);
      if (loadData != null
          && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
              || helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
        started = true;
         // 通过 loadData 的 fecher 来进行获取
        startNextLoad(loadData);
      }
    }
    return started;
  }
}
// 判断是否还有 Loader 没有执行
private boolean hasNextModelLoader() {
  return loadDataListIndex < helper.getLoadData().size();
}

final class DecodeHelper<Transcode> {
  List<LoadData<?>> getLoadData() {
    if (!isLoadDataSet) {
      isLoadDataSet = true;
      loadData.clear();
      // 通过 Registry 来获取, 记得前面提过的 Glide 创建时的 Registry 么, 就是这个
      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);
        // 通过 ModelLoader 创建 LoadData
        LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
        if (current != null) {
          loadData.add(current);
        }
      }
    }
    return loadData;
  }
}

public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
  // 获取到所有 modelClass 符合要求的 ModelLoader
  List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model));
  if (modelLoaders.isEmpty()) {
    throw new NoModelLoaderAvailableException(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);
    // 会通过 handles 函数判断 ModelLoader 是否能处理此类型的链接, 如有些处理 image 开头, 有些处理 http 开头等
    if (loader.handles(model)) {
      if (isEmpty) {
        filteredLoaders = new ArrayList<>(size - i);
        isEmpty = false;
      }
      // 将符合要求的放入到集合中,最后返回
      filteredLoaders.add(loader);
    }
  }
  if (filteredLoaders.isEmpty()) {
    throw new NoModelLoaderAvailableException(model, modelLoaders);
  }
  return filteredLoaders;
}

这个 Registry 在 Glide 创建的时候注册, 通过 append 方法添加了很多 ModelLoaderRegistry 对象, 这个就是依据 model 的类型(加载网络地址时是 String), 来筛选出适合的 Registry.

registry
     .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());

String 相关的就是这几个, 所以他们组成了一个集合被返回, 我们看看各个 Fractory 创建的 ModelLoader 的 handles 函数, 最后遗留的就是我们需要的 ModelLoader

public final class DataUrlLoader<Model, Data> implements ModelLoader<Model, Data> {

    private static final String DATA_SCHEME_IMAGE = "data:image";
    private static final String BASE64_TAG = ";base64";
    // 要求是 data:image 开头,显然这个不满足
    public boolean handles(@NonNull Model model) {
    // We expect Model to be a Uri or a String, both of which implement toString() efficiently. We
    // should reconsider this implementation before adding any new Model types.
     return model.toString().startsWith(DATA_SCHEME_IMAGE);
    }

    private static final class DataUriFetcher<Data> implements DataFetcher<Data> {
        public static final class StreamFactory<Model> implements ModelLoaderFactory<Model, InputStream> {

            private final DataDecoder<InputStream> opener;
        
            public StreamFactory() {
              opener =
                  new DataDecoder<InputStream>() {
                    @Override
                    public InputStream decode(String url) {
                      if (!url.startsWith(DATA_SCHEME_IMAGE)) {
                        throw new IllegalArgumentException("Not a valid image data URL.");
                      }
        
                      int commaIndex = url.indexOf(',');
                      if (commaIndex == -1) {
                        throw new IllegalArgumentException("Missing comma in data URL.");
                      }
        
                      String beforeComma = url.substring(0, commaIndex);
                      if (!beforeComma.endsWith(BASE64_TAG)) {
                        throw new IllegalArgumentException("Not a base64 image data URL.");
                      }
        
                      String afterComma = url.substring(commaIndex + 1);
                      byte[] bytes = Base64.decode(afterComma, Base64.DEFAULT);
        
                      return new ByteArrayInputStream(bytes);
                    }
        
                    @Override
                    public void close(InputStream inputStream) throws IOException {
                      inputStream.close();
                    }
        
                    @Override
                    public Class<InputStream> getDataClass() {
                      return InputStream.class;
                    }
                  };
            }
        
            @NonNull
            @Override
            public ModelLoader<Model, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
              return new DataUrlLoader<>(opener);
            }
        
            @Override
            public void teardown() {
              // Do nothing.
            }
          }
    }
}


public class StringLoader<Data> implements ModelLoader<String, Data> {

    public boolean handles(@NonNull String model) {
    // Avoid parsing the Uri twice and simply return null from buildLoadData if we don't handle this
    // particular Uri type.
        // StringLoader 打头的一定都满足
        return true;
    }
    public static class StreamFactory implements ModelLoaderFactory<String, InputStream> {

        @NonNull
        @Override
        public ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory multiFactory) {
            // 以 Uri.class InputStream.class 为匹配机制,去 Registry 继续匹配
            return new StringLoader<>(multiFactory.build(Uri.class, InputStream.class));
        }
    
        @Override
        public void teardown() {
          // Do nothing.
        }
      }

      /** Factory for loading {@link ParcelFileDescriptor}s from Strings. */
      public static class FileDescriptorFactory
          implements ModelLoaderFactory<String, ParcelFileDescriptor> {
    
        @NonNull
        @Override
        public ModelLoader<String, ParcelFileDescriptor> build(
            @NonNull MultiModelLoaderFactory multiFactory) {
          // 以 Uri.class 和 ParcelFileDescriptor.class 去匹配
          // 这个是处理 content 和 media 打头的内容的, 这里不做详细分析
          return new StringLoader<>(multiFactory.build(Uri.class, ParcelFileDescriptor.class));
        }
    
        @Override
        public void teardown() {
          // Do nothing.
        }
      }
    
      /** Loads {@link AssetFileDescriptor}s from Strings. */
      public static final class AssetFileDescriptorFactory
          implements ModelLoaderFactory<String, AssetFileDescriptor> {
    
        @Override
        public ModelLoader<String, AssetFileDescriptor> build(
            @NonNull MultiModelLoaderFactory multiFactory) {
          // 这个是处理 content file android.resource 的内容 这里也不做详细分析
          return new StringLoader<>(multiFactory.build(Uri.class, AssetFileDescriptor.class));
        }
    
        @Override
        public void teardown() {
          // Do nothing.
        }
      }
}

所以主要就是 Uri.class InputStream.class 来进行匹配的 Registry 内容, 由于较多,略过详细的分析过程, 直接说明最终的处理逻辑

public class HttpUriLoader implements ModelLoader<Uri, InputStream> {
  public boolean handles(@NonNull Uri model) {
    return SCHEMES.contains(model.getScheme());
  }

  /** Factory for loading {@link InputStream}s from http/https {@link Uri}s. */
  public static class Factory implements ModelLoaderFactory<Uri, InputStream> {

    @NonNull
    @Override
    public ModelLoader<Uri, InputStream> build(MultiModelLoaderFactory multiFactory) {
        // 以 GlideUrl.class InputStream.class 继续获取  
        return new HttpUriLoader(multiFactory.build(GlideUrl.class, InputStream.class));
    }

    @Override
    public void teardown() {
      // Do nothing.
    }
}

public class HttpGlideUrlLoader implements ModelLoader<GlideUrl, InputStream> {
  // 返回了 LoadData 传入的是 GlideUrl  和 HttpUrlFetcher
  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;
  }

  /** The default factory for {@link HttpGlideUrlLoader}s. */
  public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> {
    private final ModelCache<GlideUrl, GlideUrl> modelCache = new ModelCache<>(500);

    @NonNull
    @Override
    public ModelLoader<GlideUrl, InputStream> build(MultiModelLoaderFactory multiFactory) {
      return new HttpGlideUrlLoader(modelCache);
    }

    @Override
    public void teardown() {
      // Do nothing.
    }
  }
}

知道了 LoadData 及传入的 Fetcher 的类型, 接下来就执行到了 HttpUrlFetcher 的 loadData 函数来获取参数

  public void loadData(
      @NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
    long startTime = LogTime.getLogTime();
    try {
      // 执行到 loadDataWithRedirects
      InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
      callback.onDataReady(result);
    } catch (IOException e) {
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "Failed to load data for url", e);
      }
      callback.onLoadFailed(e);
    } finally {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Finished http url fetcher fetch in " + LogTime.getElapsedMillis(startTime));
      }
    }
  }

private InputStream loadDataWithRedirects(
      URL url, int redirects, URL lastUrl, Map<String, String> headers) throws IOException {
    if (redirects >= MAXIMUM_REDIRECTS) {
      throw new HttpException("Too many (> " + MAXIMUM_REDIRECTS + ") redirects!");
    } else {
      // Comparing the URLs using .equals performs additional network I/O and is generally broken.
      // See http://michaelscharf.blogspot.com/2006/11/javaneturlequals-and-hashcode-make.html.
      try {
        if (lastUrl != null && url.toURI().equals(lastUrl.toURI())) {
          throw new HttpException("In re-direct loop");
        }
      } catch (URISyntaxException e) {
        // Do nothing, this is best effort.
      }
    }

    // 通过 HttpUrlConnection 建立连接来获取数据
    urlConnection = connectionFactory.build(url);
    for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
      urlConnection.addRequestProperty(headerEntry.getKey(), headerEntry.getValue());
    }
    urlConnection.setConnectTimeout(timeout);
    urlConnection.setReadTimeout(timeout);
    urlConnection.setUseCaches(false);
    urlConnection.setDoInput(true);

    // Stop the urlConnection instance of HttpUrlConnection from following redirects so that
    // redirects will be handled by recursive calls to this method, loadDataWithRedirects.
    urlConnection.setInstanceFollowRedirects(false);

    // Connect explicitly to 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;
    }
    final int statusCode = urlConnection.getResponseCode();
    if (isHttpOk(statusCode)) {
      return getStreamForSuccessfulRequest(urlConnection);
    } else if (isHttpRedirect(statusCode)) {
      String redirectUrlString = urlConnection.getHeaderField("Location");
      if (TextUtils.isEmpty(redirectUrlString)) {
        throw new HttpException("Received empty or null redirect url");
      }
      URL redirectUrl = new URL(url, redirectUrlString);
      // Closing the stream specifically is required to avoid leaking ResponseBodys in addition
      // to disconnecting the url connection below. See #2352.
      cleanup();
      return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
    } else if (statusCode == INVALID_STATUS_CODE) {
      throw new HttpException(statusCode);
    } else {
      throw new HttpException(urlConnection.getResponseMessage(), statusCode);
    }
  }

到这里加载完成了, 最后就是设置到对应的 View 上。

第三层缓存

回到 DecodeJob 的 getNextStage 函数, 有两条链路,我们之前的分析直接跳过了缓存, 其实这里就是第三层缓存 DiskLruCache 处理的位置。

如果执行缓存, Stage 的状态为 RESOURCE_CACHE, 获取到的是 ResourceCacheGenerator, 然后就运行 ResourceCacheGenerator 的 startNext 方法。

public boolean startNext() {
    List<Key> sourceIds = helper.getCacheKeys();
    if (sourceIds.isEmpty()) {
        return false;
    }
    List<Class<?>> resourceClasses = helper.getRegisteredResourceClasses();
    if (resourceClasses.isEmpty()) {
        if (File.class.equals(helper.getTranscodeClass())) {
            return false;
        }
        throw new IllegalStateException(
            "Failed to find any load path from "
            + helper.getModelClass()
            + " to "
            + helper.getTranscodeClass());
    }
    while (modelLoaders == null || !hasNextModelLoader()) {
        resourceClassIndex++;
        if (resourceClassIndex >= resourceClasses.size()) {
            sourceIdIndex++;
            if (sourceIdIndex >= sourceIds.size()) {
                return false;
            }
            resourceClassIndex = 0;
        }

        Key sourceId = sourceIds.get(sourceIdIndex);
        Class<?> resourceClass = resourceClasses.get(resourceClassIndex);
        Transformation<?> transformation = helper.getTransformation(resourceClass);
        // PMD.AvoidInstantiatingObjectsInLoops Each iteration is comparatively expensive anyway,
        // we only run until the first one succeeds, the loop runs for only a limited
        // number of iterations on the order of 10-20 in the worst case.
        currentKey =
        new ResourceCacheKey( // NOPMD AvoidInstantiatingObjectsInLoops
            helper.getArrayPool(),
            sourceId,
            helper.getSignature(),
            helper.getWidth(),
            helper.getHeight(),
            transformation,
            resourceClass,
            helper.getOptions());
        // 通过 DiskCache 先去获取资源
        cacheFile = helper.getDiskCache().get(currentKey);
        if (cacheFile != null) {
            sourceKey = sourceId;
            modelLoaders = helper.getModelLoaders(cacheFile);
            modelLoaderIndex = 0;
        }
    }

    loadData = null;
    boolean started = false;
    while (!started && hasNextModelLoader()) {
        ModelLoader<File, ?> modelLoader = modelLoaders.get(modelLoaderIndex++);
        loadData =
        modelLoader.buildLoadData(
            cacheFile, helper.getWidth(), helper.getHeight(), helper.getOptions());
        if (loadData != null && helper.hasLoadPath(loadData.fetcher.getDataClass())) {
            started = true;
            // 获取不到再去加载
            loadData.fetcher.loadData(helper.getPriority(), this);
        }
    }

    return started;
}

这就是 Glide 的三级缓存机制。

以上就是对 Glide 加载图片的源码的详细分析过程。

个人认为其中比较重要的点在于

1、Glide 通过 SupportRequestManagerFragment 来感知生命周期;

2、Glide 的三级缓存机制;

3、Glide 的图片加载原理;

  • 20
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值