html购物网站,网站开发教程H5,域名网站有哪些,深圳福永关于安卓SVGA浅尝#xff08;二#xff09;加载数据 相关链接
SVGA官网 SVGA-github说明文档
背景
项目开发#xff0c;都会和动画打交道#xff0c;动画的方案选取#xff0c;就有很多选择。如Json动画#xff0c;svga动画#xff0c;gif等等。各有各的优势。目前项…关于安卓SVGA浅尝二加载数据 相关链接
SVGA官网 SVGA-github说明文档
背景
项目开发都会和动画打交道动画的方案选取就有很多选择。如Json动画svga动画gif等等。各有各的优势。目前项目中用到了svga的动画因此就有了这一系列的文章。
实现
对于svga的加载方法有以下几种 1decodeFromURL() 2decodeFromAssets()
对于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) {returnforEach}val fileTag byteArray.slice(IntRange(0, 3))if (fileTag[0].toInt() 73 fileTag[1].toInt() 68 fileTag[2].toInt() 51) {returnforEach}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--------------------------------------------------------------------------------