关于安卓SVGA浅尝(二)加载数据

2023-09-18 14:50:29

关于安卓SVGA浅尝(二)加载数据

请添加图片描述

相关链接

SVGA官网
SVGA-github说明文档

背景

项目开发,都会和动画打交道,动画的方案选取,就有很多选择。如Json动画,svga动画,gif等等。各有各的优势。目前项目中用到了svga的动画,因此,就有了这一系列的文章。

实现

对于svga的加载方法,有以下几种:
(1)decodeFromURL()
(2)decodeFromAssets()

对于(1)方法,就是从网络url加载一个url并在本地显示的意思。方法(2),就是读取本地assets文件进行显示。
方法(1)的实现逻辑,具体如下:
1、对传入的数据进行一个数据转换,得出一个数据缓存的key值。
2、若key值对应的缓存存在,则直接加载数据(区分是默认缓存路径还是其他缓存路径)
3、否则进行网络请求,通过HttpURLConnection请求写入得出一个ByteArrayInputStream对象后回调外部,执行
SVGAVideoEntity对象的封装后,回调出外部并交由外部执行。(这里得出ByteArrayInputStream后的逻辑,和
decodeFromAssets()方法读取文件后的逻辑,是一致的,都是调用decodeFromInputStream()这个防范进行处理)


而最后通过“流”到构建出“SVAVideoEntity”过程中,构造方法有一段这样的代码:

    constructor(entity: MovieEntity, cacheDir: File, frameWidth: Int, frameHeight: Int) {
        this.mFrameWidth = frameWidth
        this.mFrameHeight = frameHeight
        this.mCacheDir = cacheDir
        this.movieItem = entity
        entity.params?.let(this::setupByMovie)
        try {
            parserImages(entity)
        } catch (e: Exception) {
            e.printStackTrace()
        } catch (e: OutOfMemoryError) {
            e.printStackTrace()
        }
        resetSprites(entity)
    }

核心代码,就是parserImages(entity)这个方法,里面的实现源码如下:

    private fun parserImages(obj: MovieEntity) {
        obj.images?.entries?.forEach { entry ->
            val byteArray = entry.value.toByteArray()
            if (byteArray.count() < 4) {
                return@forEach
            }
            val fileTag = byteArray.slice(IntRange(0, 3))
            if (fileTag[0].toInt() == 73 && fileTag[1].toInt() == 68 && fileTag[2].toInt() == 51) {
                return@forEach
            }
            val filePath = generateBitmapFilePath(entry.value.utf8(), entry.key)
            createBitmap(byteArray, filePath)?.let { bitmap ->
                imageMap[entry.key] = bitmap
            }
        }
    }

可以看出,这里对传入对象的images集合类进行了遍历,最后通过createBitmap方法,创建了一个对象,
并且赋值给了SVAVideoEntity这个对象中的imageMap集合。
而对于parserImages方法中的入参“MovieEntity”,大部分都是通过方法“MovieEntity.ADAPTER.decode”进行对象构建。
这个方法是依赖于com.opensource.svgaplayer.proto这个包目录下的的方法在MovieEntity如下:

    @Override
    public MovieEntity decode(ProtoReader reader) throws IOException {
      Builder builder = new Builder();
      long token = reader.beginMessage();
      for (int tag; (tag = reader.nextTag()) != -1;) {
        switch (tag) {
          case 1: builder.version(ProtoAdapter.STRING.decode(reader)); break;
          case 2: builder.params(MovieParams.ADAPTER.decode(reader)); break;
          case 3: builder.images.putAll(images.decode(reader)); break;
          case 4: builder.sprites.add(SpriteEntity.ADAPTER.decode(reader)); break;
          case 5: builder.audios.add(AudioEntity.ADAPTER.decode(reader)); break;
          default: {
            FieldEncoding fieldEncoding = reader.peekFieldEncoding();
            Object value = fieldEncoding.rawProtoAdapter().decode(reader);
            builder.addUnknownField(tag, fieldEncoding, value);
          }
        }
      }
      reader.endMessage(token);
      return builder.build();
    }

最后调用的方法builder.build()核心代码如下:

    @Override
    public MovieEntity build() {
      return new MovieEntity(version, params, images, sprites, audios, super.buildUnknownFields());
    }

可以看出,整个过程,就是通过类型的判断,然后构建出对应类型的一个自定义数据对象,也就是我们的MovieEntity对象。


整个大体的加载实现思路,可以简单地描述如下:
(1)传入资源url/路径,调用对应加载方法进行加载
(2)区分网络加载还是本地加载,网络加载会先走缓存逻辑,否则直接网络io进行加载
(3)通过加载方法,最后都会生成一个IO流,传入一个处理流的通用方法里面,进行MovieEntity对象构建,回调
(4)最后通过SVGADrawable的构造,设置给SVGAImageView对象,最后调用SVGAImageView对象的startAnimation()方法,即可显示动画。


上述就是svga文件,加载到显示的整体流程,至于其中的细节,如缓存key的生成,MovieEntity对象构造,可以拉官方module
的代码进行研究。

关于svga更多的源码阅读,将会在后面的文章一一描述,本次文章先到这里。

that’s all--------------------------------------------------------------------------------

更多推荐

C语言学习:16、C语言指针

指针是C语言的精髓,很多人都觉得指针难学,是因为内心对指针有所恐惧,把自己吓退了。一种应用语言能有多难,只要了解了指针的本质,学习起来就超级简单。一、什么是指针1.1、指针就是一种变量,一种特殊的变量,就这么简单。这个特殊体现在,指针中保存的值是内存中的地址。前面了解过int型变量,char型变量,float型变量,它

C#-WinForm-发送邮件

登录QQ邮箱——设置——开启“POP3/SMTP服务”登陆QQ邮箱→打开设置→开启“POP3/SMTP服务”,获取“授权码”简单总结一下:1、使用SmtpClient发送电子邮件是很简单的,只要正确创建了MailMessage对象和SmtpClient就可以很容易的发送出去电子邮件。2、如果电子邮件服务器需要身份验证【

CH2--x86系统架构概览

2.1OVERVIEWOFTHESYSTEM-LEVELARCHITECTURE图中的实线箭头表示线性地址,虚线表示段选择器,虚线箭头表示物理地址2.1.1GlobalandLocalDescriptorTables全局描述符表(GDT)GDT是一个全局的段描述符表,它存储在系统内存中的一个固定位置。通常,GDT被加载

【kafka】kafka命令大全

概述本文将分享一些kafka经常使用的一些命令,不断完善中。管理创建主题,3个分区,2个副本对使用了zookeeper的kafkakafka-topics.sh--create--zookeeper192.168.2.140:2181,192.168.2.141:2181,192.168.2.142:2181--rep

iPhone 15秋季发布会召开,媒介盒子多家媒体持续报道

现如今互联网引流成本越来越高不说,难度越来越大,大多数都是投入巨大,收效甚微。因此,用有限的成本带来高回报的效果成为企业共同的追求。当然,企业想要产品服务引流绝非易事。为什么你的品牌营销不见效?新产品上市要怎么做宣传?盒子以新发布的苹果15为例分析,给你一些启发。1、时机很重要9月13日,苹果秋季发布会如期而至,各大媒

AERMOD模型在大气环境影响评价中的应用

随着我国经济快速发展,我国面临着日益严重的大气污染问题。近年来,严重的大气污染问题已经明显影响国计民生,引起政府、学界和人们越来越多的关注。大气污染是工农业生产、生活、交通、城市化等方面人为活动的综合结果,同时气象因素是控制大气污染的关键自然因素。大气污染问题既是局部、当地的,也是区域的,甚至是全球的。本地的污染物排放

【web开发】8、Django(3)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、管理员1.表结构2.layout.html文件下添加管理员账号的导航3.urls.py文件(POST请求传递nid)4.form.py文件(密码加密,确认密码,重置密码与原密码要求不一致)5.admin.py文件二、中间件(实现登录校验)1

【JAVA】idea初步使用+JDK详细配置

1、官方下载idea官网:DownloadIntelliJIDEA–TheLeadingJavaandKotlinIDE(1)、下载教程我下载没截屏,详细教程请看原文:手把手教你JDK+IDEA的安装和环境配置_idea配置jdk_快到锅里来呀的博客-CSDN博客2、启动项目时候需要配置JDK环境(1)、下载JDK官网

Jmeter安装与测试

目录一:JMeter简介:二:JMeter安装与配置三:JMeter主要原件一:JMeter简介:JMeter,一个100%的纯Java桌面应用,由Apache组织的开放源代码项目,它是功能和性能测试的工具。具有高可扩展性、支持Web(HTTP/HTTPS)、SOAP、FTP、JAVA等多种协议的特点。官方网站:htt

方案:浅析利用AI智能识别与视频监控技术打造智慧水产养殖监管系统

一、方案背景针对目前水产养殖集约、高产、高效、生态、安全的发展需求,基于智能传感、智慧物联网、人工智能、视频监控等技术打造智慧水产系统,成为当前行业的发展趋势。传统的人工观察水产养殖方式较为单一,难以及时发现人员非法入侵、偷盗、偷钓、水质污染等管理问题。二、方案概述TSINGSEE青犀视频智慧水产养殖方案主要是围绕视频

TDengine 与煤矿智能 AI 视频管理系统实现兼容性互认

煤矿行业是一个充满危险和复杂性的领域,具备产业规模大、分布地域广、安全性要求高等特点,为了实现智能化预警、预测等目的,煤矿企业纷纷采用现代化的技术来提高安全性、生产效率和管理水平。煤矿智能AI视频管理系统可以助力企业更好地进行矿工工作环境监测、异常情况报警等工作,从而提高安全性并减少事故风险,在煤矿项目中已经得到了广泛

热文推荐