Glide源码解析(二)

176 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

Glide源码解析(一)

基本用法

Glide最基本的用法如下:

Glide.with(context)
     .load(url)
     .into(imageView)

本文就从这三个方法去学习Glide的源码。

PS:本文基于4.13.2版本的Glide源码。

废话不多说直接开始!

load

我们通过with获得了RequestManager,而load就是是RequestManager的方法。在看load方法之前,我们先来认识一下RequestManager,它到底是什么东西,起什么作用。

说到认识一个类,最直接的方式就是看注释:

A class for managing and starting requests for Glide. Can use activity, fragment and connectivity lifecycle events to intelligently stop, start, and restart requests. Retrieve either by instantiating a new object, or to take advantage built in Activity and Fragment lifecycle handling, use the static Glide.load methods with your Fragment or Activity.

翻译一下:一个为Glide管理和启动请求的类。通过Activity、Fragment以及连接性生命周期事件智能启停和重启请求。通过实例化新对象或利用内置的 Activity 和 Fragment 生命周期处理来检索使用静态 Glide。使用你的Fragment或者Activity加载方法。

说人话就是:我也只看懂了第一句和第二句……

好了现在看看load方法:

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

传入一个String(有很多重载方法,URL、File等等,对应加载不同位置,这里只解析传入图片网址的String的情况),返回一个RequestBuilder。

RequestBuilder顾名思义就是请求的构造器,也就是说,load方法也还不是真正进行请求的地方。

asDrawable方法是为了构建ResourceType为Drawable的RequestBuilder,也是默认的ResourceType。除了Drawable之外,还有asBitmap、asFile、asGif三种ResourceType。指定ResourceType是为了能够使用对应的解码器。这里只解析Drawable,其他的ResourceType有机会再解析吧。

asDrawable最终new了一个RequestBuilder,那我们就来看看RequestBuilder的初始化做了些什么吧!

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

protected关键字表面了RequestBuilder只能从包内初始化,以免使用者自行创建不合规的RequestBuilder。

入参为:Glide实例,RequestManager实例,TranscodeType类以及Context。

基本上就是将传进来的值进行简单的赋值。

通过asDrawable构建了RequestBuilder之后,调用RequestBuilder.load方法,实际调用的是loadGeneric方法,如下:

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

由于我们传入的是String,所以model也就是我们传入的图片地址。由于传入的对象类型多种多样,所以model声明为Object对象。

selfOrThrowIfLocked则是检查改RequestBuilder是否被锁定,锁定则抛出异常,未锁定则返回自己本身。正常流程是返回本身,也就是RequestBuilder。

可以看出,load方法也只是简单的给model赋值。

load方法的流程比较简单,老规矩通过图来复习一下:

sequenceDiagram
RequestManager->>RequestManager:load()
RequestManager->>RequestManager:asDrawable()
RequestManager->>RequestBuilder:load()
RequstBuilder->>RequestBuilder:loadGeneric()
RequestBuilder->>RequestManager:requestBuilder

至此load方法也分析完毕咯!

下一篇分析最复杂的into方法。