集成
1.SVGA 的Gradle 无法下载,可以考虑导入库包的形式去支持。
2.因为导入的库有冲突,项目中有一个aar 项目中包含了OKio 1.10.0 的jar包,这种情况下,无论外部在gradle 如何去引用兼容,都会报冲突。此处的解决方式是,用解压工具直接解压aar 文件,删除lib 中冲突的jar 包,就可以解决问题。
使用
SVGA 的使用很简单,详细参见SVGA 的集成文档
坑1:
SVGA 在快速读和写入同一个文件(url 地址相同),会报错说找不到文件名。
复现,在RecyclerView 中每个Item 都显示同一个Url 地址,快速滑动,听OnError 方法,会发现不断被调用 ,跟踪代码会找到在读取缓存文件的时候抛出了异常
现象,在
SVGAParser.ParseCompletion 中频繁调用OnError
未能分析出具体原因所在
坑2:
一开始看到的现象
SVGAImageView 在RecyclerView 中时不时会出现图片消失
弯弯绕绕分析后出现的现象是
SVGAImageView 在RecyclerView 中,当SVGAImageView所在的Item 移出屏幕,再滑动回来时,SVGA的图片消失(空白)
猜想问题
1.SVGA 被移出屏幕,item 被回收,再重建的时候,没有设SVGA 图导致空白。
验证过程,在 RecyclerView onBindViewHolder 的时候,去打印log ,发现没有出现重建但是SVGA 没有填值的情况
2.猜想RecyclerView 在的的Item 复用,会影响SVGA 的重新设值。
验证:在ViewHold 创建的时候就填写好编号,并且在onBindViewHolder 的时候不去修改这个编号。
结果:验证出规律,ViewHold 的item 复用并没有那么理想,当item 超出一定范围的时候就会去重建一个View而不是复用(具体机制有待研究)并且经过创建出来的Item 肯定会播放SVGA图。在发现规律的过程中,发现了SVGA更准确的规律,只要item 移出屏幕,再拉回来就不会显示SVGA,并且这个时候并没有经过onBindViewHolder 方法去重绘。
3.猜想在item 移出屏幕的时候,对Item 做了操作。导致视图被清空。
验证:无法验证
试错:想办法在item 移入屏幕的时候重绘SVGA,(因为RecyclerView 的 onBindViewHolder 已经不可靠了)
查看View 的生命周期,onAttachedToWindow 中可以考虑处理载入SVGA,
查看SVGAImageView 源码,发现他们重写了onDetackedFromWindow 方法。其中代码片段为
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
animator?.cancel()
animator?.removeAllListeners()
animator?.removeAllUpdateListeners()
}
Debug 跟踪,在item 移出屏幕的时候,SVGAImageView 会调用这个方法。清空了所有的动画导致不显示。
解决:注释这个方法,但是考虑到资源释放的问题,在RecyclerView 中 复写 onViewRecycled 方法,在这里面主动释放SVGA