Lottie內存泄漏問題的定位與分析

點擊
「搜狗測試」
可關注咱們!

【1、前言Lottie簡介與使用android


 1Lottie簡介ios

Lottie Airbnb 開源的跨平臺動畫庫,支持 iOS Android React Native   Web  等平臺。 它能夠解析使用  Bodymovin  導出爲  json   Adobe After Effects  動畫,容許應用程序像使用靜態圖像同樣輕鬆使用動畫。

Android庫地址:https://github.com/airbnb/lottie-androidgit

iOS庫地址:https://github.com/airbnb/lottie-iosgithub

Lottie資源庫:https://lottiefiles.com/編程

2Lottie的使用流程json

(1).   動效設計人員在Adobe After Effects中設計動畫;
微信

(2).   動效設計人員經過Adobe After Effects的Bodymovin插件導出記錄動畫信息的JSON文件;框架

(3).   開發人員使用Lottie的開源庫讀取這份JSON文件進行解析和渲染異步

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 完成的。

【2、內存泄漏問題背景出現場景


背景

輸入法錄音助手SDK測試,錄音助手SDK和輸入法進程相互獨立。

問題場景

(錄音助手SDK)首頁和(輸入法)個人頁面切換,發現明顯的內存增加趨勢。

問題修復插曲

開發同窗的帳號和機器泄漏不明顯,修復其餘內存泄漏後,開發提交檢驗;但測試同窗機器和帳號內存泄漏易復現,最終開發測試一同對比定位,復現。

問題修復

修復後,(助手SDK)首頁和(輸入法)個人頁面切換,最終退出SDK,可見內存最終能夠恢復平穩,和起始內存差別不大;助手SDK進程的CPU佔用0%。

【3、問題定位與分析


結論: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


歡迎添加咱們的搜狗測試微信號,與咱們一塊兒聊聊測試


本文分享自微信公衆號 - 搜狗測試(SogouQA)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索