Android开源框架之glide (二)

源码解析

glide的使用就是:

Glide.with(this)
    .load(IMG_PATH)
    .into(imageView);

1、with()方法

@NonNull
public static RequestManager with(@NonNull Context context) {
  return getRetriever(context).get(context);
}

@NonNull
public static RequestManager with(@NonNull Activity activity) {
  return getRetriever(activity).get(activity);
}

@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
  return getRetriever(activity).get(activity);
}

@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
  return getRetriever(fragment.getActivity()).get(fragment);
}

@SuppressWarnings("deprecation")
@Deprecated
@NonNull
public static RequestManager with(@NonNull android.app.Fragment fragment) {
  return getRetriever(fragment.getActivity()).get(fragment);
}

@NonNull
public static RequestManager with(@NonNull View view) {
  return getRetriever(view.getContext()).get(view);
}

with方法有多个重载的方法,Context、Activity、FragmentActivity、Fragment、view等。

都通过getRetriever().get()返回了一个RequestManager。

getRetriever(Context context)

private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    Preconditions.checkNotNull(
        context,
        "You cannot start a load on a not yet attached View or a Fragment where getActivity() "
            + "returns null (which usually occurs when getActivity() is called before the Fragment "
            + "is attached or after the Fragment is destroyed).");
    return Glide.get(context).getRequestManagerRetriever();
}

这个方法返回了一个RequestManagerRetriever对象。Glide.get(context)这个应该就是一个Glide对象

Glide.get(context)

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

是一个双重判断的单例模式,确保Glide对象的唯一性。checkAndInitializeGlide(context)这个方法就应该是去创建Glide对象

checkAndInitializeGlide(context)

private static void checkAndInitializeGlide(@NonNull Context context) {
    if (isInitializing) {
      throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
          + " use the provided Glide instance instead");
    }
    isInitializing = true;
    initializeGlide(context);
    isInitializing = false;
}

initializeGlide(context);

private static void initializeGlide(@NonNull Context context) {
    //创建了一个GlideBuilder对象
    initializeGlide(context, new GlideBuilder());
}

private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    Context applicationContext = context.getApplicationContext();
    GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
    List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
    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;
        }
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
        }
        iterator.remove();
      }
    }

    if (Log.isLoggable(TAG, Log.DEBUG)) {
      for (com.bumptech.glide.module.GlideModule glideModule : manifestModules) {
        Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
      }
    }

    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory() : null;
    builder.setRequestManagerFactory(factory);
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.applyOptions(applicationContext, builder);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
	//生成glide对象
    Glide glide = builder.build(applicationContext);
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
      module.registerComponents(applicationContext, glide, glide.registry);
    }
    if (annotationGeneratedModule != null) {
      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
    }
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
}

这个方法很长,主要就是builder.build(applicationContext)方法,一看就知道GlideBuilder使用建造者模式去获取glide对象。

GlideBuilder的build(Context context)

@NonNull
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) {
        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) {
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              GlideExecutor.newAnimationExecutor(),
              isActiveResourceRetentionAllowed);
    }

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

    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptions.lock(),
        defaultTransitionOptions,
        defaultRequestListeners,
        isLoggingRequestOriginsEnabled);
}

用于生成glide的默认配置,主要是构建线程池(包括sourceExecutor ,diskCacheExecutor ),内存和硬盘缓存,默认的连接监听工厂(connectivityMonitorFactory ),Engine对象和RequestManagerRetriever 对象等等。

在使用的时候可以自定义这些配置,如果没有自定义就使用默认的。

有几个重要的对象创建,先看下它的构建内容:

RequestManagerRetriever

private final Handler handler;
private final RequestManagerFactory factory;

public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
  this.factory = factory != null ? factory : DEFAULT_FACTORY;
  handler = new Handler(Looper.getMainLooper(), this /* Callback */);
}

这个RequestManagerRetriever就上面with()方法中getRetriever(context)要获取的对象,它的构造方法创建了一个RequestManagerFactory工厂类,看名字就知道用于生成RequestManager的。

还新建了一个handler,用与发送消息切换线程的。

Engine对象:

public Engine(
  MemoryCache memoryCache,
  DiskCache.Factory diskCacheFactory,
  GlideExecutor diskCacheExecutor,
  GlideExecutor sourceExecutor,
  GlideExecutor sourceUnlimitedExecutor,
  GlideExecutor animationExecutor,
  boolean isActiveResourceRetentionAllowed) {
    this(
        memoryCache,
        diskCacheFactory,
        diskCacheExecutor,
        sourceExecutor,
        sourceUnlimitedExecutor,
        animationExecutor,
        /*jobs=*/ null,
        /*keyFactory=*/ null,
        /*activeResources=*/ null,
        /*engineJobFactory=*/ null,
        /*decodeJobFactory=*/ null,
        /*resourceRecycler=*/ null,
        isActiveResourceRetentionAllowed);
}

Engine(MemoryCache cache,
  DiskCache.Factory diskCacheFactory,
  GlideExecutor diskCacheExecutor,
  GlideExecutor sourceExecutor,
  GlideExecutor sourceUnlimitedExecutor,
  GlideExecutor animationExecutor,
  Jobs jobs,
  EngineKeyFactory keyFactory,
  ActiveResources activeResources,
  EngineJobFactory engineJobFactory,
  DecodeJobFactory decodeJobFactory,
  ResourceRecycler resourceRecycler,
  boolean isActiveResourceRetentionAllowed) {
    this.cache = cache;
    this.diskCacheProvider = new LazyDiskCacheProvider(diskCacheFactory);

    if (activeResources == null) {
      activeResources = new ActiveResources(isActiveResourceRetentionAllowed);
    }
    this.activeResources = activeResources;
    activeResources.setListener(this);

    if (keyFactory == null) {
      keyFactory = new EngineKeyFactory();
    }
    this.keyFactory = keyFactory;

    if (jobs == null) {
      jobs = new Jobs();
    }
    this.jobs = jobs;

    if (engineJobFactory == null) {
      engineJobFactory =
          new EngineJobFactory(
              diskCacheExecutor, sourceExecutor, sourceUnlimitedExecutor, animationExecutor, this);
    }
    this.engineJobFactory = engineJobFactory;

    if (decodeJobFactory == null) {
      decodeJobFactory = new DecodeJobFactory(diskCacheProvider);
    }
    this.decodeJobFactory = decodeJobFactory;

    if (resourceRecycler == null) {
      resourceRecycler = new ResourceRecycler();
    }
    this.resourceRecycler = resourceRecycler;

    cache.setResourceRemovedListener(this);
}

Engine对象对传进来的参数进行了封装,并创建了几个工厂类EngineKeyFactory、engineJobFactory、decodeJobFactory以及几个HashMap类型的对象集合,如:jobs ,activeResources 等等。

回到build方法中,看到最后新建了一个Glide对象。看一下Glide的构造函数

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 RequestOptions defaultRequestOptions,
  @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
  @NonNull List<RequestListener<Object>> defaultRequestListeners,
  boolean isLoggingRequestOriginsEnabled) {
    this.engine = engine;
    this.bitmapPool = bitmapPool;
    this.arrayPool = arrayPool;
    this.memoryCache = memoryCache;
    this.requestManagerRetriever = requestManagerRetriever;
    this.connectivityMonitorFactory = connectivityMonitorFactory;
    //创建DecodeFormat解码格式,默认是PREFER_ARGB_8888
    DecodeFormat decodeFormat = defaultRequestOptions.getOptions().get(Downsampler.DECODE_FORMAT);
    bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);
    
    final Resources resources = context.getResources();
    //新建一个registry对象
    registry = new Registry();
    registry.register(new DefaultImageHeaderParser());
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
      registry.register(new ExifInterfaceImageHeaderParser());
    }
    
    ......
    //
    registry.append()....register()...
    //初始化ImageViewTargetFactory
    ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
    //创建GlideContext对象
    glideContext =
        new GlideContext(
            context,
            arrayPool,
            registry,
            imageViewTargetFactory,
            defaultRequestOptions,
            defaultTransitionOptions,
            defaultRequestListeners,
            engine,
            isLoggingRequestOriginsEnabled,
            logLevel);
}

这个构造方法很长,上面将其简化,这里面创建了几个重要的对象

Registry

在Registry内部,提供了对如下几种类型模块的挂载支持:

/**
 * 数据加载模块
 */
private final ModelLoaderRegistry modelLoaderRegistry;
/**
 * 编码存储模块,提供将数据持久化存储到磁盘文件中的功能
 */
private final EncoderRegistry encoderRegistry;
/**
 * 解码模块,能够将各种类型数据,例如文件、byte数组等数据解码成bitmap或者drawable等资源
 */
private final ResourceDecoderRegistry decoderRegistry;
/**
 * 编码存储模块,提供将bitmap或者drawable等资源文件进行持久化存储的功能
 */
private final ResourceEncoderRegistry resourceEncoderRegistry;
/**
 * 数据流重定向模块,例如重定向ByteBuffer中的position或者stream中的指针位置等
 */
private final DataRewinderRegistry dataRewinderRegistry;
/**
 * 类型转换模块,提供将不同资源类型进行转换的能力,例如将bitmap转成drawable等
 */
private final TranscoderRegistry transcoderRegistry;

Registry主要是通过register和append方法添加很多的注册或解码转码方式等。

//
public <Data> Registry append(@NonNull Class<Data> dataClass, @NonNull Encoder<Data> encoder) {
  
    encoderRegistry.append(dataClass, encoder);
    return this;
}

public <Data, TResource> Registry append(
    @NonNull String bucket,
    @NonNull Class<Data> dataClass,
    @NonNull Class<TResource> resourceClass,
    @NonNull ResourceDecoder<Data, TResource> decoder) {
  
    decoderRegistry.append(bucket, decoder, dataClass, resourceClass);
    return this;
}

  public <TResource> Registry append(
    @NonNull Class<TResource> resourceClass, @NonNull ResourceEncoder<TResource> encoder) {
  
    resourceEncoderRegistry.append(resourceClass, encoder);
    return this;
}

  public <Model, Data> Registry append(
    @NonNull Class<Model> modelClass, @NonNull Class<Data> dataClass,
    @NonNull ModelLoaderFactory<Model, Data> factory) {
	
    modelLoaderRegistry.append(modelClass, dataClass, factory);
    return this;
}

public Registry register(@NonNull DataRewinder.Factory<?> factory) {
    dataRewinderRegistry.register(factory);
    return this;
}

主要是存放到不同的对象中的集合变量中。这在后面用来解析是从内存,文件或是网络获取资源有着重要的作用。

GlideContext对象

GlideContext对象在后面也扮演中重要的角色,创建这个对象到目前为止只是为了初始化和赋值

public GlideContext(
  @NonNull Context context,
  @NonNull ArrayPool arrayPool,
  @NonNull Registry registry,
  @NonNull ImageViewTargetFactory imageViewTargetFactory,
  @NonNull RequestOptions defaultRequestOptions,
  @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
  @NonNull List<RequestListener<Object>> defaultRequestListeners,
  @NonNull Engine engine,
  boolean isLoggingRequestOriginsEnabled,
  int logLevel) {
    super(context.getApplicationContext());
    this.arrayPool = arrayPool;
    this.registry = registry;
    this.imageViewTargetFactory = imageViewTargetFactory;
    this.defaultRequestOptions = defaultRequestOptions;
    this.defaultRequestListeners = defaultRequestListeners;
    this.defaultTransitionOptions = defaultTransitionOptions;
    this.engine = engine;
    this.isLoggingRequestOriginsEnabled = isLoggingRequestOriginsEnabled;
    this.logLevel = logLevel;
}

ImageViewTargetFactory

用来根据不同的Class构建target对象的.

这样Glide对象就创建完成了,回到getRetriever(@Nullable Context context)方法,返回了一个RequestManagerRetriever对象,这个对象就是build方法中创建的。

然后继续回到with()方法

public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
}

由上面知道getRetriever(activity)方法返回的RequestManagerRetriever对象,进入它的get()方法看一下,如何生成RequestManager的

public RequestManager get(@NonNull Activity activity) {
    //判断是否主线程
    if (Util.isOnBackgroundThread()) {
      //不是的话,就调用这个方法
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      //
      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) {
    //RequestManagerFragment是一个Fragment
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
	//获取RequestManager对象,第一次肯定等于null
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
     
      Glide glide = Glide.get(context);
	  //创建requestManager
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
}

这个方法中的factory就是上面在创建RequestManagerRetriever对象的构造方法中的RequestManagerFactory工程类,调用它build方法创建requestManager

private RequestManagerFragment getRequestManagerFragment(
  @NonNull final android.app.FragmentManager fm,
  @Nullable android.app.Fragment parentHint,
  boolean isParentVisible) {
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        //新建了一个Fragment
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
}

这个方法新建了一个没有界面的Fragment,这样就将保证Glide与它依赖的Context的生命周期一致

private static final RequestManagerFactory DEFAULT_FACTORY = new RequestManagerFactory() {
    @NonNull
    @Override
    public RequestManager build(@NonNull Glide glide, @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode, @NonNull Context context) {
      return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
    }
};

RequestManagerFactory工程类,调用它build方法新建一个RequestManager

这样with方法就解析完成,接下来看一下load方法

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

在调用with方法获取到RequestManager对象下,调用load方法,并传递我们的url参数。

看下asDrawable()的源码:

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

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

protected RequestBuilder(
  @NonNull Glide glide,
  RequestManager requestManager,
  Class<TranscodeType> transcodeClass,
  Context context) {
    this.glide = glide;
    this.requestManager = requestManager;
    this.transcodeClass = transcodeClass;
    this.context = context;
    this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
    this.glideContext = glide.getGlideContext();

    initRequestListeners(requestManager.getDefaultRequestListeners());
    apply(requestManager.getDefaultRequestOptions());
}

asDrawable()创建了一个RequestBuilder对象,transcodeClass就是Drawable.class

然后又调用了RequestBuilder的load方法

public RequestBuilder<TranscodeType> load(@Nullable String string) {
    return loadGeneric(string);
}

private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
}

可以看到load方法中什么也没有做,仅仅就是将URL放到model变量中,并设置isModelSet为true。

这样整个load方法就解析完了,返回了一个RequestBuilder对象,然后看一下into方法

public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
    Util.assertMainThread();
    Preconditions.checkNotNull(view);

    BaseRequestOptions<?> requestOptions = this;
    if (!requestOptions.isTransformationSet()
        && requestOptions.isTransformationAllowed()
        && view.getScaleType() != null) {
      //
      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.
      }
    }
    
    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        Executors.mainThreadExecutor());
}

由上面的解析可以看出with以及load方法并没有进行真正的加载操作,所以可以知道into方法中会进行加载操作。接下来就一步一步深入去看一下。

into(ImageView view)方法有调用了另一个into的重载方法into(Y target,RequestListener targetListener,BaseRequestOptions<?> options,Executor callbackExecutor)

先看一下glideContext.buildImageViewTarget()方法:

public <X> ViewTarget<ImageView, X> buildImageViewTarget(
  @NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
  
  return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}

transcodeClass就是load方法时再as()方法中生成的Drawable.class

imageViewTargetFactory这个对象就是之前在创建Glide的构造方法中新建的ImageViewTargetFactory

public <Z> ViewTarget<ImageView, Z> buildTarget(@NonNull ImageView view,
  @NonNull Class<Z> clazz) {
    if (Bitmap.class.equals(clazz)) {
      return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
    } else if (Drawable.class.isAssignableFrom(clazz)) {
      return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
    } else {
      throw new IllegalArgumentException(
          "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
}

从上面知道buildTarget方法中第二个参数是Drawable.class类型,所以新建DrawableImageViewTarget,并把view传递进去,

DrawableImageViewTarget继承于ImageViewTarget,又把view传递到了ViewTarget中,最终把view存放到了ViewTarget中的view变量中,并且还创建了一个SizeDeterminer对象:

public ViewTarget(@NonNull T view) {
    this.view = Preconditions.checkNotNull(view);
    sizeDeterminer = new SizeDeterminer(view);
}

这就是ImageView的最终去向,返回到RequestBuilder中,创建个DrawableImageViewTarget对象后,回到into方法中:

return into(
    glideContext.buildImageViewTarget(view, transcodeClass),
    /*targetListener=*/ null,
    requestOptions,
    Executors.mainThreadExecutor());

创建了一个Executors线程池:

public static Executor mainThreadExecutor() {
    return MAIN_THREAD_EXECUTOR;
}

private static final Executor MAIN_THREAD_EXECUTOR = new Executor() {
    private final Handler handler = new Handler(Looper.getMainLooper());

    @Override
    public void execute(@NonNull Runnable command) {
      handler.post(command);
    }
};

在执行execute方法时就会调用handler.post方法将线程切换回主线程。接下来开始进入into的重载方法

private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {
	  
	//检查target是否为null
    Preconditions.checkNotNull(target);
	//在load的时候设置为true
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }
    //构建Request对象
    Request request = buildRequest(target, targetListener, options, callbackExecutor);
    //获取target之前保存的Request对象
    Request previous = target.getRequest();
    //判断两个request是否一样
	if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
      request.recycle();
      // 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);
    //给target设置request
	target.setRequest(request);
	//加载request
    requestManager.track(target, request);

    return target;
}

一步一步看看这个into中的方法,先获取Request,看一下如何获取的,进入buildRequest方法

private Request buildRequest(
  Target<TranscodeType> target,
  @Nullable RequestListener<TranscodeType> targetListener,
  BaseRequestOptions<?> requestOptions,
  Executor callbackExecutor) {
    return buildRequestRecursive(
        target,
        targetListener,
        /*parentCoordinator=*/ null,
        transitionOptions,
        requestOptions.getPriority(),
        requestOptions.getOverrideWidth(),
        requestOptions.getOverrideHeight(),
        requestOptions,
        callbackExecutor);
}

又调用了buildRequestRecursive方法

private Request buildRequestRecursive(
  Target<TranscodeType> target,
  @Nullable RequestListener<TranscodeType> targetListener,
  @Nullable RequestCoordinator parentCoordinator,
  TransitionOptions<?, ? super TranscodeType> transitionOptions,
  Priority priority,
  int overrideWidth,
  int overrideHeight,
  BaseRequestOptions<?> requestOptions,
  Executor callbackExecutor) {

    ErrorRequestCoordinator errorRequestCoordinator = null;
    if (errorBuilder != null) {
      errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
      parentCoordinator = errorRequestCoordinator;
    }
    
    Request mainRequest =
        buildThumbnailRequestRecursive(
            target,
            targetListener,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            requestOptions,
            callbackExecutor);
    
    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(
            target,
            targetListener,
            errorRequestCoordinator,
            errorBuilder.transitionOptions,
            errorBuilder.getPriority(),
            errorOverrideWidth,
            errorOverrideHeight,
            errorBuilder,
            callbackExecutor);
    errorRequestCoordinator.setRequests(mainRequest, errorRequest);
    return errorRequestCoordinator;
}

调用buildThumbnailRequestRecursive方法生成Request对象

private Request buildThumbnailRequestRecursive(
  Target<TranscodeType> target,
  RequestListener<TranscodeType> targetListener,
  @Nullable RequestCoordinator parentCoordinator,
  TransitionOptions<?, ? super TranscodeType> transitionOptions,
  Priority priority,
  int overrideWidth,
  int overrideHeight,
  BaseRequestOptions<?> requestOptions,
  Executor callbackExecutor) {
    if (thumbnailBuilder != null) {
      // Recursive case: contains a potentially recursive thumbnail request builder.
      if (isThumbnailBuilt) {
        throw new IllegalStateException("You cannot use a request as both the main request and a "
            + "thumbnail, consider using clone() on the request(s) passed to thumbnail()");
      }
    
      TransitionOptions<?, ? super TranscodeType> thumbTransitionOptions =
          thumbnailBuilder.transitionOptions;
    
      // Apply our transition by default to thumbnail requests but avoid overriding custom options
      // that may have been applied on the thumbnail request explicitly.
      if (thumbnailBuilder.isDefaultTransitionOptionsSet) {
        thumbTransitionOptions = transitionOptions;
      }
    
      Priority thumbPriority = thumbnailBuilder.isPrioritySet()
          ? thumbnailBuilder.getPriority() : getThumbnailPriority(priority);
    
      int thumbOverrideWidth = thumbnailBuilder.getOverrideWidth();
      int thumbOverrideHeight = thumbnailBuilder.getOverrideHeight();
      if (Util.isValidDimensions(overrideWidth, overrideHeight)
          && !thumbnailBuilder.isValidOverride()) {
        thumbOverrideWidth = requestOptions.getOverrideWidth();
        thumbOverrideHeight = requestOptions.getOverrideHeight();
      }
    
      ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
      Request fullRequest =
          obtainRequest(
              target,
              targetListener,
              requestOptions,
              coordinator,
              transitionOptions,
              priority,
              overrideWidth,
              overrideHeight,
              callbackExecutor);
      isThumbnailBuilt = true;
      // Recursively generate thumbnail requests.
      Request thumbRequest =
          thumbnailBuilder.buildRequestRecursive(
              target,
              targetListener,
              coordinator,
              thumbTransitionOptions,
              thumbPriority,
              thumbOverrideWidth,
              thumbOverrideHeight,
              thumbnailBuilder,
              callbackExecutor);
      isThumbnailBuilt = false;
      coordinator.setRequests(fullRequest, thumbRequest);
      return coordinator;
    } else if (thumbSizeMultiplier != null) {
      // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
      ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
      Request fullRequest =
          obtainRequest(
              target,
              targetListener,
              requestOptions,
              coordinator,
              transitionOptions,
              priority,
              overrideWidth,
              overrideHeight,
              callbackExecutor);
      BaseRequestOptions<?> thumbnailOptions =
          requestOptions.clone().sizeMultiplier(thumbSizeMultiplier);
    
      Request thumbnailRequest =
          obtainRequest(
              target,
              targetListener,
              thumbnailOptions,
              coordinator,
              transitionOptions,
              getThumbnailPriority(priority),
              overrideWidth,
              overrideHeight,
              callbackExecutor);
    
      coordinator.setRequests(fullRequest, thumbnailRequest);
      return coordinator;
    } else {
      // Base case: no thumbnail.
      return obtainRequest(
          target,
          targetListener,
          requestOptions,
          parentCoordinator,
          transitionOptions,
          priority,
          overrideWidth,
          overrideHeight,
          callbackExecutor);
    }

}

这个方法前面都是一些缩略图的判断,直接跳过,进入最后一个else中看到又调用了obtainRequest方法

private Request obtainRequest(
  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,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        glideContext.getEngine(),
        transitionOptions.getTransitionFactory(),
        callbackExecutor);
}

返回了一个SingleRequest对象,这样就可以知道需要的request是一个SingleRequest,进到obtain方法

public static <R> SingleRequest<R> obtain(
  Context context,
  GlideContext glideContext,
  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) {
    @SuppressWarnings("unchecked") SingleRequest<R> request =
        (SingleRequest<R>) POOL.acquire();
    if (request == null) {
      request = new SingleRequest<>();
    }
    request.init(
        context,
        glideContext,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        engine,
        animationFactory,
        callbackExecutor);
    return request;

}

进行了一些初始化操作。新建了一个SingleRequest。这样调用buildRequest方法构建Request对象,是一个SingleRequest。回到into,继续看下一个target.getRequest();方法

由上面知道target是ImageViewTarget,又继承了ViewTarget,进入ViewTarget的getRequest方法看一下

public Request getRequest() {
    Object tag = getTag();
    Request request = null;
    if (tag != null) {
      if (tag instanceof Request) {
        request = (Request) tag;
      } else {
        throw new IllegalArgumentException(
            "You must not call setTag() on a view Glide is targeting");
      }
    }
    return request;
}

private Object getTag() {
    if (tagId == null) {
      return view.getTag();
    } else {
      return view.getTag(tagId);
    }
}

这里应该就比较熟悉了,这就是给request添加一个tag标记,防止图片显示错乱,由于是第一次加载,所以返回的是null。

target.getRequest();方法解析完了,继续into中的步骤,接下来就是

private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor) {

    ......

    //给target设置request
    target.setRequest(request);
    //加载request
    requestManager.track(target, request);		
	
    ......		
}

target.setRequest(request);这个方法就不再详解,就是个request设置一个tag标记,主要看一下requestManager.track(target, request);	

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

requestTracker在新建requestManager的时候创建的new RequestTracker(),进入它的runRequest

public void runRequest(@NonNull Request request) {
    requests.add(request);
    if (!isPaused) {
      request.begin();
    } else {
      request.clear();
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "Paused, delaying request");
      }
      pendingRequests.add(request);
    }
}

它将会调用Request对象的begin方法来企图开启请求,request其实就是SingleRequest对象,进入SingleRequest的begin方法

@Override
public synchronized void begin() {
    assertNotCallingCallbacks();
    stateVerifier.throwIfRecycled();
    startTime = LogTime.getLogTime();
    //判断model是否为空,model就是传进来的URL
    if (model == null) {
      if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        width = overrideWidth;
        height = overrideHeight;
      }
    
      int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
      onLoadFailed(new GlideException("Received null model"), logLevel);
      return;
    }
    //状态是否为running状态,默认是pending.Status是枚举类
    if (status == Status.RUNNING) {
      throw new IllegalArgumentException("Cannot restart a running request");
    }
    //是否状态为complete
    if (status == Status.COMPLETE) {
      onResourceReady(resource, DataSource.MEMORY_CACHE);
      return;
    }
    //设置状态为waitong_for_size
    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      onSizeReady(overrideWidth, overrideHeight);
    } else {
      target.getSize(this);
    }
    //根据Status对象状态和是否有占位图来设置加载过程中的占位图
    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));
    }
}

Util.isValidDimensions判断图片的宽高,由于没有设置,直接进入onSizeReady方法

@Override
public synchronized void onSizeReady(int width, int height) {
    stateVerifier.throwIfRecycled();
    if (IS_VERBOSE_LOGGABLE) {
      logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));
    }
    if (status != Status.WAITING_FOR_SIZE) {
      return;
    }
    //设置状态为running
    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));
    }
    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);

    if (status != Status.RUNNING) {
      loadStatus = null;
    }
    if (IS_VERBOSE_LOGGABLE) {
      logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
    }
}

onSizeReady方法中首先把State状态更改为RUNNING,然后获取到ImageView的宽高属性值,这个属性值就是要加载的图片的宽高。

Glide框架会根据请求加载图片的ImageView的宽高来进行加载相对应的宽高图片,每次根据view的大小加载的图片是不一定一样的。最后调用engine中的load方法

public synchronized <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;
    //根据keyFactory构建key对象
    EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
        resourceClass, transcodeClass, options);
    //获取内存缓存中的数据,弱引用
    EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
    if (active != null) {
      cb.onResourceReady(active, DataSource.MEMORY_CACHE);
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from active resources", startTime, key);
      }
      return null;
    }
    //获取内存缓存中的数据,LruCache
    EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
    if (cached != null) {
      cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from cache", startTime, key);
      }
      return null;
    }
    
    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<R> engineJob =
        engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);
    
    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);
}

所有重要的东西都在这里了:

<1> 通过keyFactory工厂来构建一个EngineKey对象,key关联着model,也就是url,它很根据model,view的宽高等等属性来构建一个EngineKey对象,这个对象可以用来指定缓存地址,可以用来从缓存中查找资源等。

<2> 根据创建的key对象分别调用loadFromCache和loadFromActiveResources方法来从内存中查找是否有缓存资源,如果有,则回调cb.onResourceReady来直接设置图片了。

<3> 使用engineJobFactory和decodeJobFactory构建EngineJob和DecodeJob对象,这两个对象是真正的加载资源的两个重要类。

EngineJob对象负责开启线程去加载资源,并且加载得资源后转换到主线程并进行回调;

DecodeJob是真正的执行者,它就是去网络加载资源的地方,EngineJob开启线程,真正执行的是DecodeJob

<4>engineJob.addCallback(cb, callbackExecutor);cb就是SingleRequest ,callbackExecutor就是into中创建的线程池用于切换到主线程

接下来主要看一下engineJob.start(decodeJob);方法

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

调用了线程池GlideExecutor的execute方法,进入到decodeJob的run方法进行加载

public void run() {
    GlideTrace.beginSectionFormat("DecodeJob#run(model=%s)", model);
    DataFetcher<?> localFetcher = currentFetcher;
    try {
      if (isCancelled) {
        notifyFailed();
        return;
      }
      runWrapped();
    } catch (CallbackException e) {
      throw e;
    } catch (Throwable t) {
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "DecodeJob threw unexpectedly"
            + ", isCancelled: " + isCancelled
            + ", stage: " + stage, t);
      }
      if (stage != Stage.ENCODE) {
        throwables.add(t);
        notifyFailed();
      }
      if (!isCancelled) {
        throw t;
      }
      throw t;
    } finally {
      if (localFetcher != null) {
        localFetcher.cleanup();
      }
      GlideTrace.endSection();
    }
}

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

在构造DecodeJob时调用init方法是runReason被赋值为INITIALIZE值,由此它将会进入到INITIALIZE分支中,调用getNextStage方法:

private Stage getNextStage(Stage current) {
    switch (current) {
      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);
    }
}

diskCacheStrategy是一个策略模式,就是设置的缓存策略,默认是AUTOMATIC,diskCacheStrategy.decodeCachedResource方法返回true。

因此getNextStage方法返回的是Stage.RESOURCE_CACHE,然后再回到runWrapped方法中,继续看getNextGenerator方法

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

可以看到有三个加载器:

ResourceCacheGenerator 尝试从处理过的本地资源加载图片
DataCacheGenerator     尝试从未处理过的原始本地资源加载图片
SourceGenerator        尝试从远程加载图片

这里的getNextGenerator就返回一个ResourceCacheGenerator加载器,再次回到runWrapped方法,继续执行runGenerators方法

private void runGenerators() {
    currentThread = Thread.currentThread();
    startFetchTime = LogTime.getLogTime();
    boolean isStarted = false;
	//开始循环
    while (!isCancelled && currentGenerator != null
        && !(isStarted = currentGenerator.startNext())) {
      stage = getNextStage(stage);
      currentGenerator = getNextGenerator();

      if (stage == Stage.SOURCE) {
        reschedule();
        return;
      }
    }
	
    if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
      notifyFailed();
    }
}

可以看到在while条件里调用了currentGenerator.startNext方法,这个currentGenerator就是上面的ResourceCacheGenerator记载器,进入它的startNext方法

public boolean startNext() {
    //获取sourceIds
    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);

        currentKey = new ResourceCacheKey(
              helper.getArrayPool(),
              sourceId,
              helper.getSignature(),
              helper.getWidth(),
              helper.getHeight(),
              transformation,
              resourceClass,
              helper.getOptions());
        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;
}

helper.getCacheKeys()方法

List<Key> getCacheKeys() {
    if (!isCacheKeysSet) {
      isCacheKeysSet = true;
      cacheKeys.clear();
      //获取LoadData集合
      List<LoadData<?>> loadData = getLoadData();
      //noinspection ForLoopReplaceableByForEach to improve perf
      for (int i = 0, size = loadData.size(); i < size; i++) {
        LoadData<?> data = loadData.get(i);
        if (!cacheKeys.contains(data.sourceKey)) {
          cacheKeys.add(data.sourceKey);
        }
        for (int j = 0; j < data.alternateKeys.size(); j++) {
          if (!cacheKeys.contains(data.alternateKeys.get(j))) {
            cacheKeys.add(data.alternateKeys.get(j));
          }
        }
      }
    }
    return cacheKeys;
}

可以看到首先获取LoadData集合,然后会循环这个集合,然后将loadData的sourceKey等等添加到cacheKeys集合中并返回。

进入getLoadData方法。

List<LoadData<?>> getLoadData() {
    if (!isLoadDataSet) {
      isLoadDataSet = true;
      loadData.clear();
      //获取ModelLoader集合
      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.buildLoadData得到LoadData对象
    	LoadData<?> current =
            modelLoader.buildLoadData(model, width, height, options);
        if (current != null) {
          loadData.add(current);
        }
      }
    }
    return loadData;
}

首先获取了一个ModelLoader集合。这个ModelLoader是什么东西,再进入glideContext.getRegistry().getModelLoaders去看一下

public <Model> List<ModelLoader<Model, ?>> getModelLoaders(@NonNull Model model) {
    List<ModelLoader<Model, ?>> result = modelLoaderRegistry.getModelLoaders(model);
    if (result.isEmpty()) {
        throw new NoModelLoaderAvailableException(model);
    }
    return result;
}

这个方法只是做了一个非空判断,进入modelLoaderRegistry.getModelLoaders方法

public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) {
    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.add(loader);
      }
    }
    return filteredLoaders;
}

这个方法还是没有获取到ModelLoader,再进入getModelLoadersForClass方法

private synchronized <A> List<ModelLoader<A, ?>> getModelLoadersForClass(
  @NonNull Class<A> modelClass) {
    //从缓存获取ModelLoader
    List<ModelLoader<A, ?>> loaders = cache.get(modelClass);
    if (loaders == null) {
      //没有就去获取
      loaders = Collections.unmodifiableList(multiModelLoaderFactory.build(modelClass));
      //将ModelLoader放到缓存中
      cache.put(modelClass, loaders);
    }
    return loaders;
}

先从缓存中获取ModelLoader,如果没有,就调用multiModelLoaderFactory.build方法去获取,这样就知道是在build这个方法中获取的,进去看一下

synchronized <Model> List<ModelLoader<Model, ?>> build(@NonNull Class<Model> modelClass) {
    try {
      List<ModelLoader<Model, ?>> loaders = new ArrayList<>();
      for (Entry<?, ?> entry : entries) {
      
        if (alreadyUsedEntries.contains(entry)) {
          continue;
        }
        if (entry.handles(modelClass)) {
          alreadyUsedEntries.add(entry);
          loaders.add(this.<Model, Object>build(entry));
          alreadyUsedEntries.remove(entry);
        }
      }
      return loaders;
    } catch (Throwable t) {
      alreadyUsedEntries.clear();
      throw t;
    }
}

这个方法里面终于是获取到了ModelLoader,看一下是如何获取的。

首先是去循环这个Entry集合,在集合里面调用entry.handles去拿到对应的ModelLoader,最后返回。

这里又出来一个Entry,这又是什么东西,在multiModelLoaderFactory类中找一下,可以看到这个集合是一个list集合,看一下是在什么地方添加元素的。

private <Model, Data> void add(
  @NonNull Class<Model> modelClass,
  @NonNull Class<Data> dataClass,
  @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory,
  boolean append) {
    
	Entry<Model, Data> entry = new Entry<>(modelClass, dataClass, factory);
    entries.add(append ? entries.size() : 0, entry);
}

是在multiModelLoaderFactory类add方法里面添加元素的,再往上找看这个add是在什么地方调用的。

synchronized <Model, Data> void append(
  @NonNull Class<Model> modelClass,
  @NonNull Class<Data> dataClass,
  @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
    
	add(modelClass, dataClass, factory, /*append=*/ true);
}

在append方法找到调用add方法,还是没有找到根,再往上找。看看append方法是谁调用的。

public synchronized <Model, Data> void append(
  @NonNull Class<Model> modelClass,
  @NonNull Class<Data> dataClass,
  @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
  
    multiModelLoaderFactory.append(modelClass, dataClass, factory);
    cache.clear();
}

在ModelLoaderRegistry类中的append看到了multiModelLoaderFactory.append方法的调用。

这个ModelLoaderRegistry类就熟悉了,就是在上面初始化Registry类的时候创建的,是数据加载模块,这样的话就应该能猜到它的append方法应该就是在Registry类中调用了。

public <Model, Data> Registry append(
  @NonNull Class<Model> modelClass, @NonNull Class<Data> dataClass,
  @NonNull ModelLoaderFactory<Model, Data> factory) {

    modelLoaderRegistry.append(modelClass, dataClass, factory);
    return this;
}

这个Registry.append不就是在初始化Glide时候添加的一些数据吗?由于初始化Glide的方法比较多,所以上面就没有列出来,接下来看一下就添加了写什么:

数据加载模块(modelLoaderRegistry)

append(
  @NonNull Class<Model> modelClass, @NonNull Class<Data> dataClass,
  @NonNull ModelLoaderFactory<Model, Data> factory)
  
append(Bitmap.class, Bitmap.class, UnitModelLoader.Factory.<Bitmap>getInstance())

append(GifDecoder.class, GifDecoder.class, UnitModelLoader.Factory.<GifDecoder>getInstance())

append(File.class, ByteBuffer.class, new ByteBufferFileLoader.Factory())
append(File.class, InputStream.class, new FileLoader.StreamFactory())
append(File.class, ParcelFileDescriptor.class, new FileLoader.FileDescriptorFactory())
append(File.class, File.class, UnitModelLoader.Factory.<File>getInstance())

append(int.class, InputStream.class, resourceLoaderStreamFactory)
append(int.class,ParcelFileDescriptor.class,resourceLoaderFileDescriptorFactory)
append(int.class, Uri.class, resourceLoaderUriFactory)
append(int.class,AssetFileDescriptor.class,resourceLoaderAssetFileDescriptorFactory)

append(Integer.class, InputStream.class, resourceLoaderStreamFactory)
append(Integer.class,ParcelFileDescriptor.class,resourceLoaderFileDescriptorFactory)
append(Integer.class, Uri.class, resourceLoaderUriFactory)
append(Integer.class,AssetFileDescriptor.class,resourceLoaderAssetFileDescriptorFactory)

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(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())

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,ParcelFileDescriptor.class,new AssetUriLoader.FileDescriptorFactory(context.getAssets()))
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(Uri.class, File.class, new MediaStoreFileLoader.Factory(context))
append(Uri.class, Uri.class, UnitModelLoader.Factory.<Uri>getInstance())

append(URL.class, InputStream.class, new UrlLoader.StreamFactory())

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(Drawable.class, Drawable.class, UnitModelLoader.Factory.<Drawable>getInstance())

编码存储模块,提供将数据持久化存储到磁盘文件中的功能(EncoderRegistry )

append(ByteBuffer.class, new ByteBufferEncoder())
append(InputStream.class, new StreamEncoder(arrayPool))

解码模块,能够将各种类型数据,例如文件、byte数组等数据解码成bitmap或者drawable等资源(ResourceDecoderRegistry)

append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
append(Registry.BUCKET_GIF, ByteBuffer.class, GifDrawable.class, byteBufferGifDecoder)
append(Registry.BUCKET_BITMAP_DRAWABLE,ByteBuffer.class,BitmapDrawable.class,new BitmapDrawableDecoder<>(resources, byteBufferBitmapDecoder))

append(Registry.BUCKET_GIF,InputStream.class,GifDrawable.class,new StreamGifDecoder(imageHeaderParsers, byteBufferGifDecoder, arrayPool))
append(Registry.BUCKET_BITMAP_DRAWABLE,InputStream.class,BitmapDrawable.class,new BitmapDrawableDecoder<>(resources, streamBitmapDecoder))
append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder)

append(Registry.BUCKET_BITMAP_DRAWABLE,ParcelFileDescriptor.class,BitmapDrawable.class,new BitmapDrawableDecoder<>(resources, parcelFileDescriptorVideoDecoder))
append(Registry.BUCKET_BITMAP,ParcelFileDescriptor.class,Bitmap.class,parcelFileDescriptorVideoDecoder)

append(Registry.BUCKET_BITMAP,AssetFileDescriptor.class,Bitmap.class,VideoDecoder.asset(bitmapPool))

append(Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder())

append(Registry.BUCKET_BITMAP,GifDecoder.class,Bitmap.class,new GifFrameResourceDecoder(bitmapPool))


BUCKET_APPEND_ALL

append(Uri.class, Drawable.class, resourceDrawableDecoder)
append(Uri.class, Bitmap.class, new ResourceBitmapDecoder(resourceDrawableDecoder, bitmapPool))

append(File.class, File.class, new FileDecoder())

append(Drawable.class, Drawable.class, new UnitDrawableDecoder())

编码存储模块,提供将bitmap或者drawable等资源文件进行持久化存储的功能(ResourceEncoderRegistry)

append(Bitmap.class, bitmapEncoder)
append(BitmapDrawable.class, new BitmapDrawableEncoder(bitmapPool, bitmapEncoder))
append(GifDrawable.class, new GifDrawableEncoder())

数据流重定向模块,例如重定向ByteBuffer中的position或者stream中的指针位置等(DataRewinderRegistry)

register(@NonNull DataRewinder.Factory<?> factory)

register(new ByteBufferRewinder.Factory())
register(new InputStreamRewinder.Factory(arrayPool))

类型转换模块,提供将不同资源类型进行转换的能力,例如将bitmap转成drawable等(TranscoderRegistry)

register(
  @NonNull Class<TResource> resourceClass, @NonNull Class<Transcode> transcodeClass,
  @NonNull ResourceTranscoder<TResource, Transcode> transcoder) 
  
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);

了解了这些之后再回到multiModelLoaderFactory.build方法中,这下就知道了Entry集合放的就是数据加载模块中的内容,然后调用entry.handles去匹配。

public boolean handles(@NonNull Class<?> modelClass) {
    return this.modelClass.isAssignableFrom(modelClass);
}

这个方法就是handles方法传进来的参数(String.Class)是否entry中的变量modelClass的子类,去数据加载模块中看一下有没有String.Class对应。找到下面四个:

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(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())

然后调用了这些ModelLoader的ModelLoaderFactory的build方法,这是一个工厂模式。通过build方法返回ModelLoader。就以StringLoader.StreamFactory()为例看一下:

public static class StreamFactory implements ModelLoaderFactory<String, InputStream> {

    @NonNull
    @Override
    public ModelLoader<String, InputStream> build(
        @NonNull MultiModelLoaderFactory multiFactory) {
      return new StringLoader<>(multiFactory.build(Uri.class, InputStream.class));
    }

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

可以看到build中又调用了multiFactory.build的方法,并传递了两个参数(Uri.class, InputStream.class)。进入看一下:

public synchronized <Model, Data> ModelLoader<Model, Data> build(@NonNull Class<Model> modelClass,
      @NonNull Class<Data> dataClass) {
    try {
      List<ModelLoader<Model, Data>> loaders = new ArrayList<>();
      boolean ignoredAnyEntries = false;
      for (Entry<?, ?> entry : entries) {
        if (alreadyUsedEntries.contains(entry)) {
          ignoredAnyEntries = true;
          continue;
        }
        if (entry.handles(modelClass, dataClass)) {
          alreadyUsedEntries.add(entry);
          loaders.add(this.<Model, Data>build(entry));
          alreadyUsedEntries.remove(entry);
        }
      }
      if (loaders.size() > 1) {
        return factory.build(loaders, throwableListPool);
      } else if (loaders.size() == 1) {
        return loaders.get(0);
      } else {
        if (ignoredAnyEntries) {
          return emptyModelLoader();
        } else {
          throw new NoModelLoaderAvailableException(modelClass, dataClass);
        }
      }
    } catch (Throwable t) {
      alreadyUsedEntries.clear();
      throw t;
    }
}

可以看到再次查找数据加载模块中的内容,找到为(Uri.class, InputStream.class)匹配的factory,如果找到了就并再次调用factory.build

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

找到这几个,以HttpUriLoader为例进入看一下:

public static class Factory implements ModelLoaderFactory<Uri, InputStream> {

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

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

这里又调用了multiFactory.build方法,又传进了两个参数(GlideUrl.class, InputStream.class),同理在数据加载模块中找一下:

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

进到HttpGlideUrlLoader类中看一下:

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.
    }
}

在build中可以看到最终创建了一个HttpGlideUrlLoader对象。以此类推这一次就创建了三个对象StringLoader、HttpUriLoader、HttpGlideUrlLoader。

其他的ModelLoader对象也是如此创建的。就不一一例举了。

找到对应的ModelLoader集合,就返回到modelLoaderRegistry.getModelLoaders方法,这个方法可以看到循环了ModelLoader集合,然后调用了ModelLoader的handles方法,再次过滤。

进入到每个ModelLoader看一下,这就以上面创建好的StringLoader为例:

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

    ......

    @Override
    public boolean handles(@NonNull String model) {
        return true;
    }

    ......
   
}

可以看到返回的是true。这就拿到了再次过滤后的ModelLoader。返回到modelLoaderRegistry.getModelLoaders方法,将过滤后的modelLoader集合返回。再次回到了getLoadData()方法中,这个方法遍历所有的ModelLoader,然后调用了ModelLoader.buildLoadData()方法,还是以StringLoader为例:

@Override
public LoadData<Data> buildLoadData(@NonNull String model, int width, int height,@NonNull Options options) {
    //将String解析成Uri
	Uri uri = parseUri(model);
    if (uri == null || !uriLoader.handles(uri)) {
      return null;
    }
    return uriLoader.buildLoadData(uri, width, height, options);
}

看到又调用了HttpUriLoader的buildLoadData方法。

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

又调用了HttpGlideUrlLoader中的buildLoadData方法

public LoadData<InputStream> buildLoadData(@NonNull GlideUrl model, int width, int height,
  @NonNull Options options) {
    //将model转为GlideUrl对象
    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));
}

可以看到最后创建了一个LoadData对象,并且创建了一个HttpUrlFetcher对象,并将LoadData对象返回。

再次回到了getLoadData()方法中往下看,最终是将获取的LoadData对象返回给了getCacheKeys()方法,至此getCacheKeys()方法就解析完了。

继续helper.getRegisteredResourceClasses()方法

List<Class<?>> getRegisteredResourceClasses() {
    return glideContext.getRegistry().getRegisteredResourceClasses(model.getClass(), resourceClass, transcodeClass);
} 

public <Model, TResource, Transcode> List<Class<?>> getRegisteredResourceClasses(
  @NonNull Class<Model> modelClass,
  @NonNull Class<TResource> resourceClass,
  @NonNull Class<Transcode> transcodeClass) {
    //从缓存中获取
    List<Class<?>> result =
        modelToResourceClassCache.get(modelClass, resourceClass, transcodeClass);
    
    if (result == null) {
        result = new ArrayList<>();
        //通过匹配modelClass获取dataClass
        List<Class<?>> dataClasses = modelLoaderRegistry.getDataClasses(modelClass);
        //循环dataClass
        for (Class<?> dataClass : dataClasses) {
            //通过匹配dataClass, resourceClass获取registeredResourceClasses
            List<? extends Class<?>> registeredResourceClasses =
               decoderRegistry.getResourceClasses(dataClass, resourceClass);
    	    //循环registeredResourceClasses
            for (Class<?> registeredResourceClass : registeredResourceClasses) {
                //通过匹配registeredResourceClass, transcodeClass获取registeredTranscodeClasses
    	        List<Class<Transcode>> registeredTranscodeClasses = transcoderRegistry
                   .getTranscodeClasses(registeredResourceClass, transcodeClass);
               if (!registeredTranscodeClasses.isEmpty() && !result.contains(registeredResourceClass)) {
                    //将得到的registeredResourceClass添加到集合中
    		        result.add(registeredResourceClass);
                }
            }
        }
        //添加到缓存中
        modelToResourceClassCache.put(
          modelClass, resourceClass, transcodeClass, Collections.unmodifiableList(result));
    }
    
    return result;
}

经过上面获取ModelLoader的分析,看到这个getRegisteredResourceClasses方法就应该比较熟悉了。

从缓存中获取RegisteredResourceClasses,没有的话首先通过匹配modelClass获取dataClass,进到modelLoaderRegistry.getDataClasses方法

public synchronized List<Class<?>> getDataClasses(@NonNull Class<?> modelClass) {
    return multiModelLoaderFactory.getDataClasses(modelClass);
}

synchronized List<Class<?>> getDataClasses(@NonNull Class<?> modelClass) {
    List<Class<?>> result = new ArrayList<>();
    for (Entry<?, ?> entry : entries) {
        if (!result.contains(entry.dataClass) && entry.handles(modelClass)) {
            result.add(entry.dataClass);
        }
    }
    return result;
}

在ModelLoader的分析中,知道这就是从数据加载模块中匹配DataClasses,去数据加载模块看一下:

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(String.class, InputStream.class, new DataUrlLoader.StreamFactory<String>())

匹配到之后,拿到其中的dataClass,也就是append方法中的第二个参数,比如InputStream.class等等。然后将获取的DataClasses返回。再回到getRegisteredResourceClasses方法中,继续执行。通过匹配的dataClass, resourceClass获取registeredResourceClasses,进到decoderRegistry.getResourceClasses方法中

public synchronized <T, R> List<Class<R>> getResourceClasses(@NonNull Class<T> dataClass,
  @NonNull Class<R> resourceClass) {
    List<Class<R>> result = new ArrayList<>();
    for (String bucket : bucketPriorityList) {
        List<Entry<?, ?>> entries = decoders.get(bucket);
        if (entries == null) {
            continue;
        }
        //循环所有的解码封装类
        for (Entry<?, ?> entry : entries) {
            //过滤
            if (entry.handles(dataClass, resourceClass)
              && !result.contains((Class<R>) entry.resourceClass)) {
                result.add((Class<R>) entry.resourceClass);
            }
        }
    }
    return result;
}

这个方法又是从解码模块中去匹配需要的ResourceClasses,去解码模块看一下:

append(Registry.BUCKET_GIF,InputStream.class,GifDrawable.class,new StreamGifDecoder(imageHeaderParsers, byteBufferGifDecoder, arrayPool))

append(Registry.BUCKET_BITMAP_DRAWABLE,InputStream.class,BitmapDrawable.class,new BitmapDrawableDecoder<>(resources, streamBitmapDecoder))

append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder) 

append(Registry.BUCKET_BITMAP_DRAWABLE,ParcelFileDescriptor.class,BitmapDrawable.class,new BitmapDrawableDecoder<>(resources, parcelFileDescriptorVideoDecoder))

append(Registry.BUCKET_BITMAP,ParcelFileDescriptor.class,Bitmap.class,parcelFileDescriptorVideoDecoder)  

append(Registry.BUCKET_BITMAP,AssetFileDescriptor.class,Bitmap.class,VideoDecoder.asset(bitmapPool))

匹配到了之后,拿到ResourceClasse就是append方法中的第三个参数,比如 GifDrawable ,最后返回。

再次回到getRegisteredResourceClasses方法中,继续执行。去匹配registeredTranscodeClasses。进到transcoderRegistry.getTranscodeClasses()方法中看一下:

public synchronized <Z, R> List<Class<R>> getTranscodeClasses(
  @NonNull Class<Z> resourceClass, @NonNull Class<R> transcodeClass) {
    List<Class<R>> transcodeClasses = new ArrayList<>();
    // GifDrawable -> Drawable is just the UnitTranscoder, as is GifDrawable -> GifDrawable.
    if (transcodeClass.isAssignableFrom(resourceClass)) {
        transcodeClasses.add(transcodeClass);
        return transcodeClasses;
    }
    
    for (Entry<?, ?> entry : transcoders) {
        if (entry.handles(resourceClass, transcodeClass)) {
            transcodeClasses.add(transcodeClass);
        }
    }

    return transcodeClasses;
}

这个方法分为两部分:
一部分就是如果resourceClass是transcodeClass的子类,比如GifDrawable和BitmapDrawable就是Drawable的子类,就将Drawable类型添加到集合中直接返回。

另一部分如果不是Drawable的子类,比如Bitmap,那么就需要从数据类型转换中匹配。去数据类型转换模块中看一下:

register(Bitmap.class,BitmapDrawable.class,new BitmapDrawableTranscoder(resources))

匹配到之后,再将Drawable类型添加到集合中返回。

再次回到getRegisteredResourceClasses方法中,继续执行。如果返回的registeredTranscodeClasses不为空,就将匹配到的RegisteredResourceClasses添加到集合并添加到缓存中,最后返回。这样getRegisteredResourceClasses方法就执行完成了,然后回到ResourceCacheGenerator.startNext方法中,继续往下看。

进到while循环里面,创建了一个ResourceCacheKey对象,然后根据key从硬盘缓存中获取缓存数据,由于是第一次,没有缓存,所以ResourceCacheGenerator.startNext方法最终就会返回false。然后就会回到DecodeJob的runGenerators()方法中,然后就会进入到while的循环体中,又会执行stage = getNextStage(stage);currentGenerator = getNextGenerator();这两个方法,这次拿到的就是DataCacheGenerator加载器中,第一次去加载图片的时候是没有缓存的,所以DataCacheGenerator也是拿不到数据的,这个就不详细分析了。之后就会拿到SourceGenerator加载器,去远程加载图片资源。转到SourceGenerator加载器还有一些小细节,就不深究了,接下来主要看一下是如何远程加载图片资源的。进入SourceGenerator.startNext()

public boolean startNext() {
    if (dataToCache != null) {
        Object data = dataToCache;
        dataToCache = null;
        cacheData(data);
    }
    
    if (sourceCacheGenerator != null && sourceCacheGenerator.startNext()) {
        return true;
    }
    sourceCacheGenerator = null;
    
    loadData = null;
    boolean started = false;
    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.fetcher.loadData(helper.getPriority(), this);
        }
    }
    return started;
}

private boolean hasNextModelLoader() {
    return loadDataListIndex < helper.getLoadData().size();
}

还没有获取到数据,所以前两个判断跳过,直接进入到while条件中,看hasNextModelLoader(),这个方法中调用了helper.getLoadData()方法

这个getLoadData()方法就是上面分析获取ModelLoader,最终就获取到了一个

new LoadData<>(url, new HttpUrlFetcher(url, timeout));

回到SourceGenerator.startNext()进入到while循环里面,这里面有个判断

helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())

经过上面的分析知道默认的缓存策略是AUTOMATIC,它的isDataCacheable:

public boolean isDataCacheable(DataSource dataSource) {
    return dataSource == DataSource.REMOTE;
}

看一下loadData.fetcher.getDataSource()方法,也就是HttpUrlFetcher.getDataSource方法

public DataSource getDataSource() {
    return DataSource.REMOTE;
}

可以看到这个判断是是相等的,所以进入到判断里面。调用了loadData.fetcher.loadData方法

@Override
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);
    } 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 {
        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.
        }
    }
    
    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);
    
    urlConnection.setInstanceFollowRedirects(false);
    
    urlConnection.connect();
    
    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);
        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);
    }
}

这里就看到了熟悉的HttpURLConnection,就不再进行过多的解析了,这里面有一个重定向的判断isHttpRedirect(statusCode),

private static boolean isHttpRedirect(int statusCode) {
    return statusCode / 100 == 3;
}

如果返回码是3xx重定向时,就会获取到重定向的redirectUrlString,重新加载。最大重定向次数MAXIMUM_REDIRECTS是5次。

拿到InputStream流对象之后,调用callback.onDataReady(result);回调给SourceGenerator。

这样SourceGenerator.startNext()方法就分析完了,就会调用callback.onDataReady(result);进入回调方法SourceGenerator.onDataReady看一下,

public void onDataReady(Object data) {
    DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
    if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource())) {
        dataToCache = data;
        cb.reschedule();
    } else {
        cb.onDataFetcherReady(loadData.sourceKey, data, loadData.fetcher,
          loadData.fetcher.getDataSource(), originalKey);
    }
}

默认是缓存的,所以会进入if判断中,去执行缓存操作,这里就不再进行详细的分析,经过缓存操作之后data就变成了DirectByteBuffer类型。

最终还是会调用cb.onDataFetcherReady(),这里主要关注一下Glide是如何将流对象解码和转码的。

直接进到cb.onDataFetcherReady(),也就是DecodeJob的onDataFetcherReady方法看一下:

public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher,
  DataSource dataSource, Key attemptedKey) {
    this.currentSourceKey = sourceKey;
    this.currentData = data;
    this.currentFetcher = fetcher;
    this.currentDataSource = dataSource;
    this.currentAttemptingKey = attemptedKey;
    if (Thread.currentThread() != currentThread) {
        runReason = RunReason.DECODE_DATA;
        callback.reschedule(this);
    } else {
        GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
        try {
            decodeFromRetrievedData();
        } finally {
            GlideTrace.endSection();
        }
    }
}

判断是否在同一线程,还没有进行线程切换,还是在子线程,所以跳过进入else中。然后调用 decodeFromRetrievedData 方法来解码数据:

private void decodeFromRetrievedData() {
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        logWithTimeAndKey("Retrieved data", startFetchTime,
          "data: " + currentData
              + ", cache key: " + currentSourceKey
              + ", fetcher: " + currentFetcher);
    }
    Resource<R> resource = null;
    try {
        resource = decodeFromData(currentFetcher, currentData, currentDataSource);
    } catch (GlideException e) {
        e.setLoggingDetails(currentAttemptingKey, currentDataSource);
        throwables.add(e);
    }
    if (resource != null) {
        notifyEncodeAndRelease(resource, currentDataSource);
    } else {
        runGenerators();
    }
}

创建一个Resource类型的变量,通过decodeFromData方法把输入流解码并返回给resource,由此可也看出,解码主要是在decodeFromData方法中:

private <Data> Resource<R> decodeFromData(DataFetcher<?> fetcher, Data data,
  DataSource dataSource) throws GlideException {
    try {
        if (data == null) {
            return null;
        }
        long startTime = LogTime.getLogTime();
        Resource<R> result = decodeFromFetcher(data, dataSource);
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logWithTimeAndKey("Decoded result " + result, startTime);
        }
        return result;
    } finally {
        //关闭流
        fetcher.cleanup();
    }
}

在上面获取流对象后回调,并没有进行关闭操作,是因为还需要对流进行解码操作,等操作结束后再关闭。这就是为什么在这个方法才关闭流对象。

又调用decodeFromFetcher方法来进行解码返回一个Resource:

private <Data> Resource<R> decodeFromFetcher(Data data, DataSource dataSource)
  throws GlideException {
    LoadPath<Data, ?, R> path = decodeHelper.getLoadPath((Class<Data>) data.getClass());
    return runLoadPath(data, dataSource, path);
}

这里获取到data.getClass,这个Class就是DirectByteBuffer.class,进到decodeHelper.getLoadPath()方法看一下:

<Data> LoadPath<Data, ?, Transcode> getLoadPath(Class<Data> dataClass) {
    return glideContext.getRegistry().getLoadPath(dataClass, resourceClass, transcodeClass);
}

public <Data, TResource, Transcode> LoadPath<Data, TResource, Transcode> getLoadPath(
  @NonNull Class<Data> dataClass, @NonNull Class<TResource> resourceClass,
  @NonNull Class<Transcode> transcodeClass) {
    LoadPath<Data, TResource, Transcode> result =
        loadPathCache.get(dataClass, resourceClass, transcodeClass);
    if (loadPathCache.isEmptyLoadPath(result)) {
        return null;
    } else if (result == null) {
        //调用getDecodePaths方法
        List<DecodePath<Data, TResource, Transcode>> decodePaths =
          getDecodePaths(dataClass, resourceClass, transcodeClass);
        if (decodePaths.isEmpty()) {
            result = null;
        } else {
            result = new LoadPath<>(
                dataClass, resourceClass, transcodeClass, decodePaths, throwableListPool);
        }
        loadPathCache.put(dataClass, resourceClass, transcodeClass, result);
    }
    return result;
}

从上面分析知道resourceClass是Object.class,transcodeClass则是Drawable.class。

首先从loadPathCache缓存中获取LoadPath对象,如果没有则调用getDecodePaths方法进行获取:

private <Data, TResource, Transcode> List<DecodePath<Data, TResource, Transcode>> getDecodePaths(
  @NonNull Class<Data> dataClass, @NonNull Class<TResource> resourceClass,
  @NonNull Class<Transcode> transcodeClass) {
  
    List<DecodePath<Data, TResource, Transcode>> decodePaths = new ArrayList<>();
    //获取registeredResourceClasses
    List<Class<TResource>> registeredResourceClasses =
        decoderRegistry.getResourceClasses(dataClass, resourceClass);
    
    for (Class<TResource> registeredResourceClass : registeredResourceClasses) {
        //获取registeredTranscodeClasses
        List<Class<Transcode>> registeredTranscodeClasses =
            transcoderRegistry.getTranscodeClasses(registeredResourceClass, transcodeClass);
        
        for (Class<Transcode> registeredTranscodeClass : registeredTranscodeClasses) {
            //获取decoders
            List<ResourceDecoder<Data, TResource>> decoders =
                decoderRegistry.getDecoders(dataClass, registeredResourceClass);
    	    //获取transcoder
            ResourceTranscoder<TResource, Transcode> transcoder =
                transcoderRegistry.get(registeredResourceClass, registeredTranscodeClass);
            @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
            DecodePath<Data, TResource, Transcode> path =
                new DecodePath<>(dataClass, registeredResourceClass, registeredTranscodeClass,
                    decoders, transcoder, throwableListPool);
            decodePaths.add(path);
        }
    }
    return decodePaths;
}

先从decoderRegistry.getResourceClasses方法中获取已经注册的registeredResourceClasses。这个在上面已经分析过了,只是上面分析时dataClass是String类型

而这次是DirectByteBuffer类型,这个DirectByteBuffer类型就是InputStream流经过缓存之后转化的。直接去解码模块找一下:

append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
append(Registry.BUCKET_GIF, ByteBuffer.class, GifDrawable.class, byteBufferGifDecoder)
append(Registry.BUCKET_BITMAP_DRAWABLE,ByteBuffer.class,BitmapDrawable.class,new BitmapDrawableDecoder<>(resources, byteBufferBitmapDecoder))

拿到的就是GifDrawable、BitmapDrawable、Bitmap。

然后循环registeredResourceClasses,调用transcoderRegistry.getTranscodeClasses获取去registeredTranscodeClasses,这个上面也分析过了,拿到的就是Drawable

然后获取decoders解码:

byteBufferBitmapDecoder、byteBufferGifDecoder、BitmapDrawableDecoder

获取transcoder转码:

BitmapDrawableTranscoder、UnitTranscoder、UnitTranscoder

最后放到decodePaths集合中,返回。再回到glideContext.getRegistry().getLoadPath,继续执行就是将集合封装成了LoadPath对象。

然后回到decodeFromFetcher方法中,可以看到调用了runLoadPath(data, dataSource, path)方法:

private <Data, ResourceType> Resource<R> runLoadPath(Data data, DataSource dataSource,
  LoadPath<Data, ResourceType, R> path) throws GlideException {
    Options options = getOptionsWithHardwareConfig(dataSource);
    DataRewinder<Data> rewinder = glideContext.getRegistry().getRewinder(data);
    try {
        // ResourceType in DecodeCallback below is required for compilation to work with gradle.
        return path.load(
            rewinder, options, width, height, new DecodeCallback<ResourceType>(dataSource));
    } finally {
        rewinder.cleanup();
    }
}

调用glideContext.getRegistry()获取Registry对象,然后调用Registry的getRewinder获取装置器,跟进去看看:

public <X> DataRewinder<X> getRewinder(@NonNull X data) {
    return dataRewinderRegistry.build(data);
}

看一下dataRewinderRegistry的内容

register(new ByteBufferRewinder.Factory())
register(new InputStreamRewinder.Factory(arrayPool))

获取到factory之后调用dataRewinderRegistry.register方法注册到Map集合rewinders中去:

public synchronized void register(@NonNull DataRewinder.Factory<?> factory) {
    rewinders.put(factory.getDataClass(), factory);
}

再来看看factory.getDataClass()都获取到哪些key:

在ByteBufferRewinder.Factory中调用getDataClass()获取的key是ByteBuffer.class

在InputStreamRewinder.Factory中调用getDataClass()获取的key是InputStream.class

返回到getRewinder方法中,调用dataRewinderRegistry对象的build方法到底做了什么:

public synchronized <T> DataRewinder<T> build(@NonNull T data) {
Preconditions.checkNotNull(data);
    DataRewinder.Factory<T> result = (DataRewinder.Factory<T>) rewinders.get(data.getClass());
    if (result == null) {
        for (DataRewinder.Factory<?> registeredFactory : rewinders.values()) {
            if (registeredFactory.getDataClass().isAssignableFrom(data.getClass())) {
                result = (DataRewinder.Factory<T>) registeredFactory;
                break;
            }
        }
    }
    
    if (result == null) {
        result = (DataRewinder.Factory<T>) DEFAULT_FACTORY;
    }
    return result.build(data);
}

在build的方法中总共做了四件事:

<1> 从rewinders集合中获取到和data.getClass()相匹配的Factory对象,从上面的分析中,知道rewinders注册的只有两个key,分别是ByteBuffer.class和InputStream.class,

data.getClass()是一个ByteBuffer.class,由此可以匹配成功。这个result就是ByteBufferRewinder.Factory对象。

<2> 假如result没有匹配成功的话,也就是没有通过key匹配成功,那么就进行遍历rewinders集合,通过values值进行匹配,把匹配成功的Factory对象再赋值给result。

<3> 假如通过键key和值values都没有匹配成功,那么也不要紧,直接使用默认的DEFAULT_FACTORY

<4> 最后调用result的build方法。

通过键key直接已匹配成功,ByteBufferRewinder.Factory对象,那么来看看调用它的build方法做了什么事情:

public DataRewinder<ByteBuffer> build(ByteBuffer data) {
    return new ByteBufferRewinder(data);
}

直接的返回了一个ByteBufferRewinder对象.再次定位到DecodeJob类中的runLoadPath方法,在获取到ByteBufferRewinder后,它会调用path.load方法并返回Resource资源类

public Resource<Transcode> load(DataRewinder<Data> rewinder, @NonNull Options options, int width,
  int height, DecodePath.DecodeCallback<ResourceType> decodeCallback) throws GlideException {
    List<Throwable> throwables = Preconditions.checkNotNull(listPool.acquire());
    try {
        return loadWithExceptionList(rewinder, options, width, height, decodeCallback, throwables);
    } finally {
        listPool.release(throwables);
    }
}

private Resource<Transcode> loadWithExceptionList(DataRewinder<Data> rewinder,
  @NonNull Options options,
  int width, int height, DecodePath.DecodeCallback<ResourceType> decodeCallback,
  List<Throwable> exceptions) throws GlideException {
    Resource<Transcode> result = null;
    //noinspection ForLoopReplaceableByForEach to improve perf
    for (int i = 0, size = decodePaths.size(); i < size; i++) {
        DecodePath<Data, ResourceType, Transcode> path = decodePaths.get(i);
        try {
            //解码
            result = path.decode(rewinder, width, height, options, decodeCallback);
        } catch (GlideException e) {
            exceptions.add(e);
        }
        if (result != null) {
            break;
        }
    }
    
    if (result == null) {
        throw new GlideException(failureMessage, new ArrayList<>(exceptions));
    }
    
    return result;
}

这个loadWithExceptionList方法首先遍历decodePaths,获取一个DecodePath调用decode方法进行解吗:

public Resource<Transcode> decode(DataRewinder<DataType> rewinder, int width, int height,
  @NonNull Options options, DecodeCallback<ResourceType> callback) throws GlideException {
    //解码获取资源
    Resource<ResourceType> decoded = decodeResource(rewinder, width, height, options);
    Resource<ResourceType> transformed = callback.onResourceDecoded(decoded);
    return transcoder.transcode(transformed, options);
}

@NonNull
private Resource decodeResource(DataRewinder rewinder, int width,
int height, @NonNull Options options) throws GlideException {
List exceptions = Preconditions.checkNotNull(listPool.acquire());
try {
//解码
return decodeResourceWithList(rewinder, width, height, options, exceptions);
} finally {
listPool.release(exceptions);
}
}

decode方法中调用decodeResource方法,然后在调用decodeResourceWithList方法真正的开始解码:

@NonNull
private Resource<ResourceType> decodeResourceWithList(DataRewinder<DataType> rewinder, int width,
  int height, @NonNull Options options, List<Throwable> exceptions) throws GlideException {
    Resource<ResourceType> result = null;
    //循环解码器
    for (int i = 0, size = decoders.size(); i < size; i++) {
        ResourceDecoder<DataType, ResourceType> decoder = decoders.get(i);
        try {
            //获取DataType
            DataType data = rewinder.rewindAndGet();
    	    //匹配解码器
            if (decoder.handles(data, options)) {
              data = rewinder.rewindAndGet();
    	      //开始解码
              result = decoder.decode(data, width, height, options);
            }
        } catch (IOException | RuntimeException | OutOfMemoryError e) {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
              Log.v(TAG, "Failed to decode data for " + decoder, e);
            }
            exceptions.add(e);
        }
        //有一个匹配到就跳出循环
        if (result != null) {
            break;
        }
    }
    //匹配不成功,抛出异常
    if (result == null) {
      throw new GlideException(failureMessage, new ArrayList<>(exceptions));
    }
    return result;
}

<1> 这里面的decoders里面只有一个解码器byteBufferGifDecoder

<2> 获取DataType ,进入rewinder.rewindAndGet();

public ByteBuffer rewindAndGet() {
    buffer.position(0);
    return buffer;
}

<3> 通过decoder.handles(data, options)方法来过滤掉不相匹配的解码器,看一下byteBufferGifDecoder中的handles方法:

public boolean handles(@NonNull InputStream source, @NonNull Options options) throws IOException {
    return !options.get(GifOptions.DISABLE_ANIMATION)
      && ImageHeaderParserUtils.getType(parsers, source, byteArrayPool) == ImageType.GIF;
}

可以看到这个解码器适用于处理GIF格式的图片,而这里是普通的图片。所以匹配不成功。抛出异常。不处理,继续回到loadWithExceptionList方法。

遍历获取下一个DecodePath。这次获取的是byteBufferBitmapDecoder。来看一下byteBufferBitmapDecoder解码器的handles方法:

public boolean handles(@NonNull ByteBuffer source, @NonNull Options options) {
    return downsampler.handles(source);
}

public boolean handles(@SuppressWarnings("unused") ByteBuffer byteBuffer) {
    return true;
}

可以看到downsampler.handles(source)总是返回true。匹配成功。调用decoder.decode开始解码

public Resource<Bitmap> decode(@NonNull ByteBuffer source, int width, int height,
  @NonNull Options options)
  throws IOException {
    InputStream is = ByteBufferUtil.toStream(source);
    return downsampler.decode(is, width, height, options);
}

将ByteBuffer转为InputStream流对象,调用downsampler.decode进行解码

public Resource<Bitmap> decode(InputStream is, int outWidth, int outHeight,
  Options options) throws IOException {
    return decode(is, outWidth, outHeight, options, EMPTY_CALLBACKS);
}

public Resource<Bitmap> decode(InputStream is, int requestedWidth, int requestedHeight,
  Options options, DecodeCallbacks callbacks) throws IOException {
    Preconditions.checkArgument(is.markSupported(), "You must provide an InputStream that supports"
        + " mark()");
    
    byte[] bytesForOptions = byteArrayPool.get(ArrayPool.STANDARD_BUFFER_SIZE_BYTES, byte[].class);
    BitmapFactory.Options bitmapFactoryOptions = getDefaultOptions();
    bitmapFactoryOptions.inTempStorage = bytesForOptions;
    
    DecodeFormat decodeFormat = options.get(DECODE_FORMAT);
    DownsampleStrategy downsampleStrategy = options.get(DownsampleStrategy.OPTION);
    boolean fixBitmapToRequestedDimensions = options.get(FIX_BITMAP_SIZE_TO_REQUESTED_DIMENSIONS);
    boolean isHardwareConfigAllowed = options.get(ALLOW_HARDWARE_CONFIG) != null && options.get(ALLOW_HARDWARE_CONFIG);
    
    try {
        Bitmap result = decodeFromWrappedStreams(is, bitmapFactoryOptions,
            downsampleStrategy, decodeFormat, isHardwareConfigAllowed, requestedWidth,
            requestedHeight, fixBitmapToRequestedDimensions, callbacks);
        return BitmapResource.obtain(result, bitmapPool);
    } finally {
      releaseOptions(bitmapFactoryOptions);
      byteArrayPool.put(bytesForOptions);
    }
}

就是通过requestedWidth、requestedHeight、options等将流进行一些操作,最终返回了Resource对象。解码完后。

回到DecodePath.decode方法,可以看到调用transcoder.transcode(transformed, options),

在上面的分析中可以知道byteBufferBitmapDecoder对应的transcoder转码器是BitmapDrawableTranscoder,进入它的transcode()方法看一下:

public Resource<BitmapDrawable> transcode(@NonNull Resource<Bitmap> toTranscode,
  @NonNull Options options) {
    return LazyBitmapDrawableResource.obtain(resources, toTranscode);
}

public static Resource<BitmapDrawable> obtain(
  @NonNull Resources resources, @Nullable Resource<Bitmap> bitmapResource) {
    if (bitmapResource == null) {
        return null;
    }
    return new LazyBitmapDrawableResource(resources, bitmapResource);

}

private LazyBitmapDrawableResource(@NonNull Resources resources,
    @NonNull Resource<Bitmap> bitmapResource) {
    this.resources = Preconditions.checkNotNull(resources);
    this.bitmapResource = Preconditions.checkNotNull(bitmapResource);
}

把Bitmap封装到LazyBitmapDrawableResource对象中进行返回。到这里其实已完成了解码和封装。再次loadWithExceptionList方法,

如果返回的结果不为空的话就跳出循环,不再执行下一个DecodePath,然后返回。一直往上回到DecodeJob.decodeFromRetrievedData(),

如果resource不为null的话,就调用notifyEncodeAndRelease(resource, currentDataSource);方法:

private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {
    if (resource instanceof Initializable) {
        ((Initializable) resource).initialize();
    }
    
    Resource<R> result = resource;
    LockedResource<R> lockedResource = null;
    if (deferredEncodeManager.hasResourceToEncode()) {
        lockedResource = LockedResource.obtain(resource);
        result = lockedResource;
    }
    
    notifyComplete(result, dataSource);
    
    stage = Stage.ENCODE;
    try {
        if (deferredEncodeManager.hasResourceToEncode()) {
            deferredEncodeManager.encode(diskCacheProvider, options);
        }
    } finally {
        if (lockedResource != null) {
            lockedResource.unlock();
        }
    }
    onEncodeComplete();

}

调用notifyComplete方法:

private void notifyComplete(Resource<R> resource, DataSource dataSource) {
    setNotifiedOrThrow();
    callback.onResourceReady(resource, dataSource);
}  

调用了callback.onResourceReady(resource, dataSource);方法,这个callback是EngineJob实现:

public void onResourceReady(Resource<R> resource, DataSource dataSource) {
    synchronized (this) {
        this.resource = resource;
        this.dataSource = dataSource;
    }
    notifyCallbacksOfResult();
}

调用了notifyCallbacksOfResult()方法

void notifyCallbacksOfResult() {
    ResourceCallbacksAndExecutors copy;
    Key localKey;
    EngineResource<?> localResource;
    synchronized (this) {
        stateVerifier.throwIfRecycled();
        if (isCancelled) {
            resource.recycle();
            release();
            return;
        } else if (cbs.isEmpty()) {
            throw new IllegalStateException("Received a resource without any callbacks to notify");
        } else if (hasResource) {
            throw new IllegalStateException("Already have resource");
        }
        engineResource = engineResourceFactory.build(resource, isCacheable);
        hasResource = true;
        copy = cbs.copy();
        incrementPendingCallbacks(copy.size() + 1);
        
        localKey = key;
        localResource = engineResource;
    }
    
    listener.onEngineJobComplete(this, localKey, localResource);
    
    for (final ResourceCallbackAndExecutor entry : copy) {
        entry.executor.execute(new CallResourceReady(entry.cb));
    }
    decrementPendingCallbacks();
}  

<1> 调用engineResourceFactory.build(resource, isCacheable)将resource封装

<2> entry.executor.execute方法切换回主线程,这个executor就是最开始调用RequestBuilder.into方法是创建的线程池对象。

看一下execute(new CallResourceReady(entry.cb))中的CallResourceReady对象。

private class CallResourceReady implements Runnable {

    private final ResourceCallback cb;
    
    CallResourceReady(ResourceCallback cb) {
      this.cb = cb;
    }
    
    @Override
    public void run() {
        synchronized (EngineJob.this) {
            if (cbs.contains(cb)) {
                engineResource.acquire();
                callCallbackOnResourceReady(cb);
                removeCallback(cb);
            }
            decrementPendingCallbacks();
        }
    }
}

调用了callCallbackOnResourceReady方法:

synchronized void callCallbackOnResourceReady(ResourceCallback cb) {
    try {
        cb.onResourceReady(engineResource, dataSource);
    } catch (Throwable t) {
        throw new CallbackException(t);
    }
}

这个cb是ResourceCallback的接口,也就是SingleRequest就实现了这个接口:

public synchronized void onResourceReady(Resource<?> resource, DataSource dataSource) {
    stateVerifier.throwIfRecycled();
    loadStatus = null;
    if (resource == null) {
        GlideException exception = new GlideException("Expected to receive a Resource<R> with an "
            + "object of " + transcodeClass + " inside, but instead got null.");
        onLoadFailed(exception);
        return;
    }
    //获取资源
    Object received = resource.get();
    if (received == null || !transcodeClass.isAssignableFrom(received.getClass())) {
        releaseResource(resource);
        GlideException exception = new GlideException("Expected to receive an object of "
            + transcodeClass + " but instead" + " got "
            + (received != null ? received.getClass() : "") + "{" + received + "} inside" + " "
            + "Resource{" + resource + "}."
            + (received != null ? "" : " " + "To indicate failure return a null Resource "
            + "object, rather than a Resource object containing null data."));
        onLoadFailed(exception);
        return;
    }
    
    if (!canSetResource()) {
        releaseResource(resource);
        // We can't put the status to complete before asking canSetResource().
        status = Status.COMPLETE;
        return;
    }
    //调用重载onResourceReady
    onResourceReady((Resource<R>) resource, (R) received, dataSource);
}

首先获取资源,从上面的分析知道resource是engineResource对象,看一下get方法:

public Z get() {
    return resource.get();
}

这个方法又调用没有封装成engineResource对象前的resource的get方法,也就是LazyBitmapDrawableResource对象

public BitmapDrawable get() {
    return new BitmapDrawable(resources, bitmapResource.get());
}

这个方法就直接将resources也就是将Bimap封装成了BitmapDrawable对象。资源对象获取成功之后,有调用了一个重载的onResourceReady方法

private synchronized void onResourceReady(Resource<R> resource, R result, DataSource dataSource) {
    // We must call isFirstReadyResource before setting status.
    boolean isFirstResource = isFirstReadyResource();
    status = Status.COMPLETE;
    this.resource = resource;
    
    if (glideContext.getLogLevel() <= Log.DEBUG) {
        Log.d(GLIDE_TAG, "Finished loading " + result.getClass().getSimpleName() + " from "
            + dataSource + " for " + model + " with size [" + width + "x" + height + "] in "
            + LogTime.getElapsedMillis(startTime) + " ms");
    }
    
    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);
            target.onResourceReady(result, animation);
        }
    } finally {
        isCallingCallbacks = false;
    }
    
    notifyLoadSuccess();
}

在onResourceReady方法中调用了target.onResourceReady(result, animation);在load方法中已讲解过,就是DrawableImageViewTarget对象,

调用它的onResourceReady会转移到父类ImageViewTarget中

public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
    if (transition == null || !transition.transition(resource, this)) {
        setResourceInternal(resource);
    } else {
        maybeUpdateAnimatable(resource);
    }
}

然后在调用setResourceInternal方法:

private void setResourceInternal(@Nullable Z resource) {
    setResource(resource);
    maybeUpdateAnimatable(resource);
}

setResource是抽象方法,由它的子类实现,我们在回到DrawableImageViewTarget中:

protected void setResource(@Nullable Drawable resource) {
    view.setImageDrawable(resource);
}

到这里直接调用view进行设置图片了,这个view就是我们Imageview了,整个加载的图片的过程就结束了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值