当前位置: 首页 > news >正文

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

关于安卓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 = frameWidththis.mFrameHeight = frameHeightthis.mCacheDir = cacheDirthis.movieItem = entityentity.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如下:

    @Overridepublic 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()核心代码如下:

    @Overridepublic 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--------------------------------------------------------------------------------

相关文章:

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

关于安卓SVGA浅尝&#xff08;二&#xff09;加载数据 相关链接 SVGA官网 SVGA-github说明文档 背景 项目开发&#xff0c;都会和动画打交道&#xff0c;动画的方案选取&#xff0c;就有很多选择。如Json动画&#xff0c;svga动画&#xff0c;gif等等。各有各的优势。目前项…...

使用matlab产生二维动态曲线视频文件具体举例

使用matlab产生二维动态曲线视频文件举例 在进行有些函数变化过程时候&#xff0c;需要用到直观的动态显示&#xff0c;本博文将举例说明利用Matlab编程进行二维动态曲线的生成视频文件。 一、问题描述 利用matlab编程实现 y 1 s i n ( t ) , y 2 c o s ( t ) , y 3 s i …...

Selenium自动化测试框架常见异常分析及解决方法

01 pycharm中导入selenium报错 现象: pycharm中输入from selenium import webdriver, selenium标红 原因1: pycharm使用的虚拟环境中没有安装selenium, 解决方法: 在pycharm中通过设置或terminal面板重新安装selenium 原因2: 当前项目下有selenium.py,和系统包名冲突导致, …...

[TI] [Textual Inversion] An image is worth an word

自己的理解&#xff1a; 根据几个图像&#xff0c;找出来一个关键字可以代表它们&#xff0c;然后我们可以再用这个关键字去生成新的东西。 提出关键字 1 Introduction word->token->embedding Textual Inversion过程 需要&#xff1a; ① a fixed, pre-trained text…...

remote: The project you were looking for could not be found

git拉取公司项目时报错&#xff1a; remote: The project you were looking for could not be found 发生这个问题的原因&#xff0c;在于git账号可能并未真正登录。 我们可以通过打开电脑的凭据管理器&#xff0c;查看git当前的登录是否正常。 参考链接&#xff1a;参考...

https跳过SSL认证时是不是就是不加密的,相当于http?

https跳过SSL认证时是不是就是不加密的,相当于http?&#xff0c;其实不是&#xff0c;HTTPS跳过SSL认证并不相当于HTTP&#xff0c;也不意味着没有加密。请注意以下几点&#xff1a; HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;本质上是在HTTP的基础上…...

linux下链接

linux下链接用法 ln链接格式与介绍 linux下链接用法一、链接的使用格式二、链接的介绍 一、链接的使用格式 链接&#xff1a; 格式&#xff1a; ln 源文件 链接文件 硬链接 ln -s 源文件 链接文件 软连接 硬链接文件占磁盘空间 但是删除源文件不会影响硬链接文件 软链接文件不…...

OpenCV项目开发实战--主成分分析(PCA)的特征脸应用(附C++/Python实现源码)

什么是主成分分析? 这是理解这篇文章的先决条件。 图 1:使用蓝线和绿线显示 2D 数据的主要组成部分(红点)。 快速回顾一下,我们了解到第一个主成分是数据中最大方差的方向。第二主成分是空间中与第一主成分垂直(正交)的最大方差方向,依此类推。第一和第二主成分红点(2…...

多层感知机——MLP

源代码在此处&#xff1a;https://github.com/wepe/MachineLearning/tree/master/DeepLearning Tutorials/mlp 一、多层感知机&#xff08;MLP&#xff09;原理简介 多层感知机&#xff08;MLP&#xff0c;Multilayer Perceptron&#xff09;也叫人工神经网络&#xff08;ANN&…...

HttpClientr入门

HttpClientr入门 介绍 HttpClient是Apache Jakarta Common下的子项目&#xff0c;可以用来提供高效的&#xff0c;最新的、功能丰富的支持HTTP协议的客户端编程工具包&#xff0c;并且它支持HTTP协议的版本和建议。 依赖导入 <dependency><groupId>org.apache.…...

网关-开放API接口签名验证方案

接口安全问题 请求身份是否合法&#xff1f;请求参数是否被篡改&#xff1f;请求是否唯一&#xff1f; AppId&AppSecret 请求身份 为开发者分配AppId&#xff08;开发者标识&#xff0c;确保唯一&#xff09;和AppSecret&#xff08;用于接口加密&#xff0c;确保不易被…...

Linux知识点 -- 网络基础 -- 传输层

Linux知识点 – 网络基础 – 传输层 文章目录 Linux知识点 -- 网络基础 -- 传输层一、传输层协议1.端口号2.网络相关bash命令 二、UDP协议1.UDP报文的解包与交付2.理解UDP报文3.UDP协议的特点4.UDP应用层IO类接口5.UDP的缓冲区6.UDP使用注意事项7.基于UDP的应用层协议 三、TCP协…...

计算机视觉与深度学习-经典网络解析-AlexNet-[北邮鲁鹏]

这里写目录标题 AlexNet参考文章AlexNet模型结构AlexNet共8层&#xff1a;AlexNet运作流程 简单代码实现重要说明重要技巧主要贡献 AlexNet AlexNet 是一种卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;的架构。它是由Alex Krizhevsky、Il…...

Django学习笔记-实现联机对战(下)

笔记内容转载自 AcWing 的 Django 框架课讲义&#xff0c;课程链接&#xff1a;AcWing Django 框架课。 CONTENTS 1. 编写移动同步函数move_to2. 编写攻击同步函数shoot_fireball 1. 编写移动同步函数move_to 与上一章中的 create_player 同步函数相似&#xff0c;移动函数的同…...

一文了解什么SEO

搜索引擎优化 (SEO) 是一门让页面在 Google 等搜索引擎中排名更高的艺术和科学。 一、搜索引擎优化的好处 搜索引擎优化是在线营销的关键部分&#xff0c;因为搜索是用户浏览网络的主要方式之一。 搜索结果以有序列表的形式呈现&#xff0c;网站在该列表中的排名越高&#x…...

SpringBoot+Jpa+Thymeleaf实现增删改查

SpringBootJpaThymeleaf实现增删改查 这篇文章介绍如何使用 Jpa 和 Thymeleaf 做一个增删改查的示例。 1、pom依赖 pom 包里面添加Jpa 和 Thymeleaf 的相关包引用 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.…...

最快的包管理器--pnpm创建vue项目完整步骤

1.用npm全局安装pnpm npm install -g pnpm 2.在要创建vue项目的包下进入cmd&#xff0c;输入&#xff1a; pnpm create vue 3.输入项目名字&#xff0c;选择Router,Pinia,ESLint,Prettier之后点确定 4.cd到创建好的项目 &#xff0c;安装依赖 cd .\刚创建好的项目名称\ p…...

算法通过村第九关-二分(中序遍历)黄金笔记|二叉搜索树

文章目录 前言1. 有序数组转二叉搜索树2. 寻找连个正序数组的中位数总结 前言 提示&#xff1a;有时候&#xff0c;我感觉自己一辈子活在两个闹钟之间&#xff0c;早上的第一次闹钟&#xff0c;以及5分钟之后的第二次闹钟。 --奥利弗萨克斯《意识的河流》 每个专题都有简单题&a…...

Mock.js之Element-ui搭建首页导航与左侧菜单

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《springMvc使用》 ⛺️ 生活的理想&#xff0c;为了不断更新自己 ! 1、Mock.js的使用 1.1.什么是Mock.js Mock.js是一个模拟数据的生成器&#xff0c;用来帮助前…...

robotframework在Jenkins执行踩坑

1. Groovy Template file [robot_results.groovy] was not found in $JENKINS_HOME/email_template 1.需要在managed files 添加robot_results.groovy。这个名字需要和配置在构建项目里default content一致&#xff08;Extended E-mail Notification默认设置里Default Content…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...