Glide源码解析三(注册组件)

这篇具有很好参考价值的文章主要介绍了Glide源码解析三(注册组件)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

转载请标明出处,维权必究: https://www.cnblogs.com/tangZH/p/12900387.html

  • Glide源码解析一,初始化
  • Glide源码解析二—into方法
  • Glide源码解析三(注册组件)
  • Glide源码解析四(解码和转码)
  • Glide自定义组件注册
  • 通过Glide加载不可见的图片

 文章来源地址https://www.toymoban.com/news/detail-657809.html

本文基于Glide 4.11.0

 

这里说的注册便是Glide初始化过程中,对解码器,编码器等的注册。

具体初始化过程可以看http://77blogs.com/?p=269。

 

本文主要讲初始化过程中,注册到底做了什么,注册的这些又存储在哪里。

比如源码中的下面代码:

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

可以在glide初始化过程中看到执行注册的是Register对象,我们可以进去看看。

private final ModelLoaderRegistry modelLoaderRegistry;
private final EncoderRegistry encoderRegistry;
private final ResourceDecoderRegistry decoderRegistry;
private final ResourceEncoderRegistry resourceEncoderRegistry;
private final DataRewinderRegistry dataRewinderRegistry;
private final TranscoderRegistry transcoderRegistry;
private final ImageHeaderParserRegistry imageHeaderParserRegistry;

可以看到很多个相关的类。

ModelLoaderRegistry :注册模型加载器相关

EncoderRegistry:注册编码器相关

ResourceDecoderRegistry:注册资源解码器相关

ResourceEncoderRegistry :注册资源编码器相关

DataRewinderRegistry:数据类型对应的资源数据相关

TranscoderRegistry:注册转码器相关

ImageHeaderParserRegistry :解析图片文件头的解析器相关

 

一、模型加载器

如源码中:

registry
        .append(int.class, InputStream.class, resourceLoaderStreamFactory)

将int类型加载为InputStream类型,加载器为resourceLoaderStreamFactory,比如我们加载图片的时候传递给glide的是一个资源id,那么glide会运用resourceLoaderStreamFactory

模型加载器将该资源id加载为InputStream,之后再是解码的过程。

 

进去发现它会调用:

modelLoaderRegistry.append(modelClass, dataClass, factory);

 

接着在ModelLoaderRegistry里面会调用:

multiModelLoaderFactory.append(modelClass, dataClass, factory);

 

追溯代码最终到这里:

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

它会构造一个Entry

public Entry(
        @NonNull Class<Model> modelClass,
        @NonNull Class<Data> dataClass,
        @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) {
      this.modelClass = modelClass;
      this.dataClass = dataClass;
      this.factory = factory;
    }

然后存放于一个list里面,这个list在multiModelLoaderFactory里。

private final List<Entry<?, ?>> entries = new ArrayList<>();

 

二、编码器

如源码中的:

registry
        .append(ByteBuffer.class, new ByteBufferEncoder())

将ByteBuffer类型数据编码为一个文件存放下来,编码器为ByteBufferEncoder

 

进去里面可以发现他调用了EncoderRegistry的append方法,然后构造一个Entry,存放在EncoderRegistry的一个集合里面:

private final List<Entry<?>> encoders = new ArrayList<>();

 

三、资源解码器

如源码中:

registry
        .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)

将ByteBuffer类型解码为Bitmap类型,解码器为byteBufferBitmapDecoder

而Registry.BUCKET_BITMAP代表的是一种类型,因为每种类型可以对应多种解码器,如:

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

 

我们最终来到这个方法:

public synchronized <T, R> void append(
    @NonNull String bucket,
    @NonNull ResourceDecoder<T, R> decoder,
    @NonNull Class<T> dataClass,
    @NonNull Class<R> resourceClass) {
  getOrAddEntryList(bucket).add(new Entry<>(dataClass, resourceClass, decoder));
}

getOrAddEntryList返回的是一个List<Entry<?, ?>>类型,里面存放着构造好的Entry实体类。这个List其实存放的是同样类型的解码器,比如都是Registry.BUCKET_BITMAP类型的,而这个整个List存放在一个map里面,key就是Registry.BUCKET_BITMAP。

 

private final Map<String, List<Entry<?, ?>>> decoders = new HashMap<>();

 

private synchronized List<Entry<?, ?>> getOrAddEntryList(@NonNull String bucket) {
  if (!bucketPriorityList.contains(bucket)) {
    // Add this unspecified bucket as a low priority bucket.
    bucketPriorityList.add(bucket);
  }
  List<Entry<?, ?>> entries = decoders.get(bucket);
  if (entries == null) {
    entries = new ArrayList<>();
    decoders.put(bucket, entries);
  }
  return entries;
}

getOrAddEntryList方法里面,通过bucketPriorityList判断是否已经有了一个这个类型的list,有的话直接从map获取该list,然后将注册的放进去。

 

四、资源编码器

如源码中:

如:

.append(GifDrawable.class, new GifDrawableEncoder())

将GifDrawable资源类型进行编码,编码器为:GifDrawableEncoder,GifDrawableEncoder里面主要是将gif数据保存为文件,对gif进行磁盘缓存的时候便需要用到这个编码器。

存储的过程与之前的类似,存在list中。

 

五、转码器

如源码中的:

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

将Bitmap转化为BitmapDrawable,转码器为BitmapDrawableTranscoder

 

存储过程类似。

 

六、ImageHeaderParserRegistry 

如源码中的:

registry.register(new DefaultImageHeaderParser());

默认的image文件头的解析器,可以由这个解析器判断图片类型,这也是用同样的代码能够加载动图与静图的原因。

 

存储过程类似。

 

至于DataRewinderRegistry 还未细看,后面再来补充,后面也会继续更新Glide相关的源码解析。

 

到了这里,关于Glide源码解析三(注册组件)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaScript 异步解决方案 Promise 全解析(转载)

    Promise 是一个 JS 的异步编程解决方案,解决了传统异步编程回调地狱的问题。 从语义上来说: Promise 是一个向外部传达异步编程操作消息的对象。 JS里一个promise可以有以下几种基本状态: nothing happened yet \\\"locked in\\\" to another promise fulfilled rejected 其中{1,2}为 pending ,{3,4}为 settl

    2024年02月08日
    浏览(60)
  • React源码解析18(5)------ 实现函数组件【修改beginWork和completeWork】

    经过之前的几篇文章,我们实现了基本的jsx,在页面渲染的过程。但是如果是通过函数组件写出来的组件,还是不能渲染到页面上的。 所以这一篇,主要是对之前写得方法进行修改,从而能够显示函数组件,所以现在我们在index.js文件中,修改一下jsx的写法。修改成函数组件

    2024年02月13日
    浏览(37)
  • FFmpeg 解析Glide 缓存下的图片文件报错(Impossible to open xxx)

    简单介绍下背景 我们业务有个功能把图片放到一个文件中,统一进行播放 ,但是遇到一个棘手问题,某一个情况下 的图片 就是打不开 就是报错。以为是编译参数 。哪些格式没有加上。但经过测试 该加的都加了。 所以 不是编译参数的问题。 Impossible to open \\\'/data/user/0/com.x

    2024年02月08日
    浏览(36)
  • ZooKeeper源码解析——学习ApacheZookeeper原理,掌握其核心组件的数据模型、监听通知机制等

    作者:禅与计算机程序设计艺术 随着互联网的飞速发展,各种信息数据越来越多,数据的存储也越来越依赖于分布式文件系统或NoSQL数据库。而传统的单机数据库往往不具备弹性可扩展性和高可用容错能力,在面对海量数据时难免会遇到性能瓶颈。为了解决这一问题,人们又

    2024年02月10日
    浏览(39)
  • stable-diffusion-webui的基础功能手动安装,了解代码结构、依赖、模型出处

    Stable Diffusion `一键安装包( 解压即用 防爆显存 ):https://www.bilibili.com/video/BV1iM4y1y7oA/ 相关博文: 1.stable-diffusion-webui安装(2):扩展模块extensions——汉化、双语等 2. stable-diffusion 训练GUI安装——lora、dreambooth 虽然,当前 B站 有很多stable-diffusion-webui 的一键安装包,但是不易

    2024年01月19日
    浏览(58)
  • vue3深入组件: 组件注册

    一个 Vue 组件在使用前需要先被“注册”,这样 Vue 才能在渲染模板时找到其对应的实现。组件注册有两种方式:全局注册和局部注册。 全局注册 我们可以使用 Vue 应用实例的 .component() 方法,让组件在当前 Vue 应用中全局可用。 全局注册的问题: 全局注册,但并没有被使用

    2024年01月18日
    浏览(40)
  • Vue全局组件和局部组件的注册

      组件的简介 : 组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树: 组件的基本使用: 创建一个Vue实例需要创建后才能使用,组件也需要进行注册后才能使用。注册

    2023年04月23日
    浏览(47)
  • 19-普通组件的注册使用

    一. 组件注册的两种方式: 1. 局部注册 :只能在注册的组件内使用         (1) 创建 vue 文件(单文件组件)         (2) 在 使用的组件内 导入,并注册 components:{ 组件名: 组件对象 }          2. 全局注册 :所有组件内都能直接使用(不需要再次导入)         (1) 创建 .vue文件(单文

    2024年02月12日
    浏览(35)
  • SpringBoot注册web组件

    目录 前言 一、注册Servlet组件 1.1  使用SpringBoot注解加继承HttpServet类注册 1.2 通过继承HttpServet类加配置类来进行注册 二、注册Listener组件 2.1  使用SpringBoot注解和实现ServletContextListener接口注册 2.2 ServletContextListener接口和配置类来进行注册 三、注册Filter组件 3.1  使用SpringB

    2024年02月08日
    浏览(10)
  • Vue 注册组件介绍

    Vue组件是一种可复用的Vue实例,用于封装可重用的HTML元素、JavaScript代码和CSS样式。它可以让开发者更好地组织和复用代码,使Web应用程序更加可维护和可扩展 Vue组件通常由三部分组成:模板(template)、数据(data)和方法(methods)。 模板:用于定义组件的 结构和布局 ;

    2024年02月04日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包