Glide如何从File中解析出Gif图片

本文详细阐述了Glide如何从磁盘读取ByteBuffer,使用ByteBufferGifDecoder解析成GifDrawableResource,并在ImageView中实现Gif动画循环播放的过程。解析关键涉及DecodeJob、LoadPath和DecodePath,以及GifDrawable的Animatable接口实现。
摘要由CSDN通过智能技术生成

本文基于 Glide从磁盘加载图片资源的流程,介绍了 Glide 是如何根据 ByteBuffer 解析出 Gif 动图的,并如何实现 Gif 动画循环♻️。

// 假设通过这种方式下载并注入 Gif 图片
Glide.with(this)
     .load("https://example.com/foo.gif")
     .into(binding.ivThumbnail)

前情提要:
前一篇文章 介绍了 Glide 如何从网络中下载图片,缓存到磁盘,并从磁盘缓存中加载得到 File,解析得到 ByteBuffer。DataCacheGenerator#startNext 中从磁盘中加载得到 File,并使用 ByteBufferFetcher 将 File 加载成 ByteBuffer,然后一连串通知走到 DecodeJob#onDataFetcherReady,最后 DecodeJob#decodeFromData 解析得到 Resource 对象。

ByteBuffer 解析得到 GifDrawableResource

现在我们就看看 ByteBuffer 是如何解析得到 Resource<GifDrawable> 的。

#decodeFromData -> DecodeJob#decodeFromFetcher,主要过程就两步,首先创建 LoadPath,然后用 LoadPath#load 加载得到 Resource。LoadPath 其实又是用内部的 DecodePath 列表来对 ByteBuffer 解码的,DecodePath#decodeResourceWithList 中会从其内部 decoders 列表中找到可以 handles ByteBuffer 和 option 的解码器。所以重点关注 DecodePath 是如何得到 decoders 列表的。

  1. LoadPath 的创建,还是用到 Glide 初始时配置的 Registry, Registry#getLoadPath 中,先找到 DecodePath 列表,再用其创建 LoadPath。
  // DecodeJob
  private <Data> Resource<R> decodeFromFetcher(Data data, DataSource dataSource)
      throws GlideException {
   
    // ❤️ LoadPath 的创建
    LoadPath<Data, ?, R> path = decodeHelper.getLoadPath((Class<Data>) data.getClass());
    return runLoadPath(data, dataSource, path);
  }
  1. 生成 DecodePath 列表,需要用到 dataClass, resourceClass, transcodeClass,在我们的使用实例中 load(String).into(ImageView),对应的三个类为 ByteBuffer.class,Object.class,Drawable.class。

  2. 1️⃣首先从 ResourceDecodeRegistry 中,根据 dataClass,resourceClass 找到所有支持的 registeredResourceClass 列表,这个支持是指,注册是使用了 <? super dataClass, ? extends resurceClass>,确保能解析成功;2️⃣接着,进入一层 for 循环,从 TranscoderRegistry 中,根据 registeredResourceClass 列表中每一项和 transcodeClass,找到所有支持的 registeredTranscodeClass 列表,这里的支持是指,注册时使用了 <? super resurceClass, ? extends transcodeClass>;3️⃣最后,在第二层 for 循环中,用 dataClass、registeredResourceClass、registeredTranscodeClass 创建 DecodePath 列表。

  // Registry
  private <Data, TResource, Transcode> List<DecodePath<Data, TResource, Transcode>> getDecodePaths(
      @NonNull Class<Data> dataClass,
      @NonNull Class<TResource> resourceClass,
      @NonNull Class<Transcode> transcodeClass) {
   
    Lis
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值