Lottie内存泄漏问题的定位与分析

Stella981
• 阅读 723

Lottie内存泄漏问题的定位与分析

点击

“搜狗测试”

可关注我们!

【一、前言Lottie简介与使用****】

 1Lottie****简介

Lottie 是 Airbnb 开源的跨平台动画库,支持 iOS 、 Android 、 React Native  和  Web  等平台。 它可以解析使用  Bodymovin  导出为  json  的  Adobe After Effects  动画,允许应用程序像使用静态图像一样轻松使用动画。

Android库地址:https://github.com/airbnb/lottie-android

iOS库地址:https://github.com/airbnb/lottie-ios

Lottie资源库:https://lottiefiles.com/

2Lottie****的使用流程

(1).   动效设计人员在Adobe After Effects中设计动画;

(2).   动效设计人员通过Adobe After Effects的Bodymovin插件导出记录动画信息的JSON文件;

(3). 开发人员使用Lottie的开源库读取这份JSON文件进行解析和渲染。

Lottie内存泄漏问题的定位与分析

3Lottie****方案的优点

(1).    动画由设计使用专业的动画制作工具Adobe After Effects来实现,使动画实现更加方便,动画效果也更好,100% 还原。

(2).   使用lottie方案,json文件大小会比gif文件小很多,性能也会更好。

(3).    简单的实现、控制动画的播放,开发效率大大提高。

(4).    可动态配置下发,实时替换动画效果。

4lottie-android 两种引入方式

xml方式

编程方式

5Lottie****实现原理

Lottie使用通过Bodymovin插件导出的json文件作为动画数据源,(json文件把图片中的元素进行来拆分,并且描述每个元素的动画执行路径和执行时间)。Lottie的读取这些数据,然后绘制到屏幕上。

首先要解析json,建立数据到对象的映射,然后根据数据对象创建合适的Drawable绘制到view上,动画的实现可以通过操作读取到的元素完成。具体过程如下所示

json文件——>Component——>Drawable——>View

通过如下3个核心类来来完成整个工作流程

(1).    LottieComposition(json->数据对象)

Lottie使用LottieComposition来作为After Effects的数据对象,即把Json文件映射为到LottieComposition,该类中提供了解析json的静态方法

(2).    LottieDrawable(数据对象->Drawable)

绘制

Lottie 的核心是 LottieDrawable,它承载了所有的绘制工作,LottieAnimationView则是对LottieDrawable 的封装,再附加了一些例如解析的功能。

(3).    LottieAnimationView(绘制)

操作集合,LottieAnimationView继承自 AppCompatImageView,封装了一些动画的操作,具体的绘制委托 LottieDrawable 完成的。

【二、内存泄漏问题背景出现场景

背景

输入法录音助手SDK测试,录音助手SDK和输入法进程相互独立。

问题场景

(录音助手SDK)首页和(输入法)我的页面切换,发现明显的内存增长趋势。

Lottie内存泄漏问题的定位与分析

问题修复插曲

开发同学的账号和机器泄漏不明显,修复其他内存泄漏后,开发提交检验;但测试同学机器和账号内存泄漏易复现,最终开发测试一同对比定位,复现。

问题修复

修复后,(助手SDK)首页和(输入法)我的页面切换,最终退出SDK,可见内存最终可以恢复平稳,和起始内存差异不大;助手SDK进程的CPU占用0%。

Lottie内存泄漏问题的定位与分析

【三、问题定位与分析

结论:lottie本身的状态处理有bug 导致泄漏了,MemoryLeak in LottieDrawable。

lottieview在detach的时候会停止动画,如果无法停止,就会导致内存泄漏。

小编场景分析:

进首页->退出,很有可能动画还没开始,就要被停止掉,所以就释放不了资源。

代码分析

lottie依赖onDetachedFromWindow停止动画,动画的play可能是异步的,在onDetachedFromWindow 中会判断当前是否在动画中,如果在动画中才会停止动画,删除异步任务,但此时可能并不再动画中,但有一个已经post出去的异步任务,在detach 后动画会执行。

加载动画是异步的,加载完成才会进入播放状态。如果compositionLayer == null 的时候,会加入到task里,没开始播放。

Lottie内存泄漏问题的定位与分析

播放开始了running= true;

Lottie内存泄漏问题的定位与分析

removeFrameCallback,running = false;

Lottie内存泄漏问题的定位与分析

onDetachedFromWindow停止动画

detach 处理时,先判断是不是播放状态,如果是播放状态running == true,才会去 cancel。但有可能加载动画完成发生在 detach 之后。

Lottie内存泄漏问题的定位与分析

官方:Lottie的新版本修改了这个问题,但Lottie 3.0.0以上版本必须要项目支持android X。

评估:这个改动需要把所有第三方框架都进行升级,对小编所在项目成本太高,暂不可行。

目前处理:重写LottieAnimationView继承,然后在ondetachedfromwindow里直接cancle。无论是否在动画中都调用一次 cancelAnimation, 取消动画,删除可能存在的异步任务。

Lottie内存泄漏问题的定位与分析

【参考****】

Lottie 官方文档:http://airbnb.io/lottie/

Lottie Github:https://github.com/airbnb/lottie-android

https://zhuanlan.zhihu.com/p/41339812

https://juejin.im/entry/58a324d12f301e00695da316

https://juejin.im/post/5a31ea836fb9a0451705367c

https://juejin.im/post/5d19fb53e51d45598611b9b6

欢迎添加我们的搜狗测试微信号,与我们一起聊聊测试Lottie内存泄漏问题的定位与分析 Lottie内存泄漏问题的定位与分析

本文分享自微信公众号 - 搜狗测试(SogouQA)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Stella981 Stella981
2年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Easter79 Easter79
2年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
2个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这