前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Lottie内存泄漏问题的定位与分析

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

作者头像
用户5521279
发布2020-07-07 11:59:14
6.9K0
发布2020-07-07 11:59:14
举报
文章被收录于专栏:搜狗测试

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

1、Lottie简介

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/

2、Lottie的使用流程

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

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

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

3、Lottie方案的优点

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

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

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

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

4、lottie-android 两种引入方式

xml方式

编程方式

5、Lottie实现原理

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)首页和(输入法)我的页面切换,发现明显的内存增长趋势。

问题修复插曲

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

问题修复

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

【三、问题定位与分析】

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

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

小编场景分析:

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

代码分析

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

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

播放开始了running= true;

removeFrameCallback,running = false;

onDetachedFromWindow停止动画

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

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

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

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

【参考】

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 搜狗测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,助力维护团队卓越代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档