专栏首页伟大程序猿的诞生Glide4.0源码全解析(二),load()背后的故事

Glide4.0源码全解析(二),load()背后的故事

书接上文,上回书说到GlideAPP和.with()方法背后的故事,那么我们接着按照我们开始的思路,按照Glide基本加载步骤中的三步走,with()load()into(),今天 我们来介绍一下load()方法。

load()方法全面解析

通过上一篇文章Glide4.0源码全解析(一),GlideAPP和.with()方法背后的故事 我们可以知道.with()方法返回的是GlideRequests对象,

/**
 * @see Glide#with(Activity)
 */
 public static GlideRequests with(Activity activity) {
   return (GlideRequests) Glide.with(activity);
 }

那么我们想要了解的.load()一定是在 GlideRequests类里面,那么先来看一下GlideRequests这个类:

public class GlideRequests extends RequestManager {
    ...
    ...
    ...
}

GlideRequests是继承自RequestManager(负责管理和请求Glide的请求类,后面再详细讲解)。 GlideRequests中有如下方法:

总共有9个方法,其他的方法暂时先不去分析,我们先去分析一下我们的load(Object arg0)方法。

该方法调用的是父类的super.load(arg0)返回的是GlideRequest对象。

那么我们去RequestManager(上门提过)看一下里面的load(arg0)方法。

先来看一下RequestManager API: Class RequestManager API

/**
 *用于管理和启动Glide请求的类。可以使用activity、fragment和连接生命周期事件来智能地停止、
 *启动和重启请求。通过实例化一个新对象,或者利用在Fragment和Activity生命周期处理中构建的
 *优势,可以在Fragment或者Activity使用静态的Glide.load方法
 */
public class RequestManager implements LifecycleListener {
  /**
   * 一个helper方法,相当于调用asDrawable()
   *
   * @return 返回一个新的给定model的request builder
   */
  public RequestBuilder<Drawable> load(@Nullable Object model) {
    return asDrawable().load(model);
  }

  /**
   *默认情况下,可以返回一个BitmapDrawable或GifDrawable,但是如果对其他可绘制的子类注册了
   *额外的解码器,那么这些子类也可以返回。
   */
  public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
  }

  /**
   *尝试使用仍和注册的资源去解码给定的类或子类
   *@param resourceClass 需要解码的资源
   *@return 一个新的加载给定资源类的request builder
   */
  public <ResourceType> RequestBuilder<ResourceType> as(Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass);
  }
}

也就是说我们在调用.load(args)时候,Glide默认帮我们执行了asDrawable()方法,asDrawable()实际执行的是as(Drawable.class),最终as(Class<ResourceType> resourceClass)返回一个RequestBuilder<>(glide, this, resourceClass);

到这里我们只是创建了一个RequestBuilder,然后我们去看

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

中的.load(model)做了什么?

既然asDrawable()返回RequestBuilder对象,那么我们就去RequestBuilder类中一探究竟。

老规矩,先来看一下RequestBuilder API: RequestBuilder API

  /**
   * 设置要加载数据的特定模型
   *
   * 这个方法至少要调用一次
   */
  @SuppressWarnings("unchecked")
  public RequestBuilder<TranscodeType> load(@Nullable Object model) {
    return loadGeneric(model);
  }

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

上面的方法我们看到load(我们传入特定的modle) 到这里你可能会疑问:为什么必须至少调用一次load()方法?传入的model在哪里使用的?

为什么必须至少调用一次load()方法?

其实不用看代码,想象都明白,你不传入资源文件,Glide为我们加载什么东西?

如上图,源码注释中也说道了,不过就算你不调用load()方法也不会出问题,因为isModelSet参数就是用来判断是否调用了load()方法,Glide已经帮我们处理好了。 如图:

所以保证了不会crash。

传入的model在哪里使用的?

传入的model会在最后的into()方法中去使用,

public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) {
    ...
    Request request = buildRequest(target);
    ...
}

private Request buildRequest(Target<TranscodeType> target) {
    return buildRequestRecursive(target, null, transitionOptions, requestOptions.getPriority(),
        requestOptions.getOverrideWidth(), requestOptions.getOverrideHeight());
  }

private Request buildRequestRecursive(Target<TranscodeType> target,
      @Nullable ThumbnailRequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority, int overrideWidth, int overrideHeight) {
    ...
    Request fullRequest = obtainRequest(target, requestOptions, coordinator, transitionOptions,
          priority, overrideWidth, overrideHeight);
      RequestOptions thumbnailOptions = requestOptions.clone()
          .sizeMultiplier(thumbSizeMultiplier);

      Request thumbnailRequest = obtainRequest(target, thumbnailOptions, coordinator,
          transitionOptions, getThumbnailPriority(priority), overrideWidth, overrideHeight);
    ...
}

private Request obtainRequest(Target<TranscodeType> target,
      RequestOptions requestOptions, RequestCoordinator requestCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions, Priority priority,
      int overrideWidth, int overrideHeight) {
    requestOptions.lock();

    return SingleRequest.obtain(
        context,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        requestListener,
        requestCoordinator,
        context.getEngine(),
        transitionOptions.getTransitionFactory());
  }

以上部分代码已经精简过来,关于into()方法本章先不介绍,下一篇将详细介绍。 到这里 .load()方法已经基本结束了。

这里只介绍了load(@Nullable Object model),总共有七个,原理都是一样的,这里就不挨着介绍了。

好了 .load(),还是比较简单的,下一篇会继续我们的三步走,讲解.into()方法。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微信小程序开发--【Hello World 及代码结构】(二)

    通过上一篇我们已经完成了注册及开发环境的搭建,今天我们来开发我们的第一个微信小程序 微信小程序开发注册流程

    先知先觉
  • Android ADB动态查看内存信息之Watch使用

    这个命令相信大家都不陌生,就是查看内存信息,那这会你应该明白我们的效果通过什么来实现的了吧,那就是watch。

    先知先觉
  • 【React Native 安卓开发】----第三方框架的引用之React-native-Swiper框架实现欢迎页【第五篇】

    今天要介绍的是React-native-Swiper这个RN开源框架,如果你不想用第三方的你也可以自己用viewPagerAndroid去实现,这里先不做介绍了...

    先知先觉
  • 用vim编辑器编辑二进制文件

    素描
  • 用Java实现JVM第五章《指令集和解释器》

    本案例通过java代码实现jvm规范中指令集和解释器,完成后就可以开始执行1到100的加和计算。

    小傅哥
  • 用Java实现JVM第五章《指令集和解释器》

    案例介绍 本案例通过java代码实现jvm规范中指令集和解释器,完成后就可以开始执行1到100的加和计算。

    小傅哥
  • Fundebug录屏插件更新至0.4.0,修复BUG,优化性能

    Fundebug是专业的程序BUG监控服务,当线上应用出现BUG的时候,我们可以第一时间报警,帮助开发者及时发现BUG,提高Debug效率。

    Fundebug
  • 对标Bert?刷屏的GPT 2.0意味着什么

    最近朋友圈被NLP的技术大新闻刷屏刷得有点多,昨天(2月15日)中午开始又被GPT 2.0刷屏了,大致看了下新闻大致了解了下思路,觉得好像思路还好,但是看GPT...

    AI科技大本营
  • HTML编码规范建议

    解释: 对于非 HTML 标签之间的缩进,比如 script 或 style 标签内容缩进,与 script 或 style 标签的缩进同级。 示例:

    前端博客 : alili.tech
  • 云计算是什么?你现在需要知道的一切

    公共云使客户无需投资新硬件或软件即可获得新功能。相反,他们向云计算提供商支付订阅费或仅为他们使用的资源付费。只需填写Web表单,用户就可以设置账户,并启动虚拟机...

    静一

扫码关注云+社区

领取腾讯云代金券