2021年6月9日 星期三

Memory Leak Fix: when use timer in viewholder

當開始使用 Leakcanary 之後,我的興趣就從寫 code 變成找 Memory Leak (以下簡稱ml)了XD

debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'

上一間公司跟目前的公司都有大量的  ml 供我玩耍,每次面試官問我你做了哪些事情解決 ml,我還真的沒什麼好說的,好好的方法用對可以嗎?

今天看著公司首頁的 banner 換一張圖,memory usage 就飆一下,不對勁阿!

看著 Leaks 那隻小雞還小鴨一直跳出來心情就很差,原本還在看業務邏輯,受不了只好來改一下。

今天遇到的問題跟上一間公司一樣,幾乎每間公司都會有一個 auto scroll 的 banner,不知道為什麼都不用 Third-party,雖然實作起來也就是一個 viewPager 加定時器而已,但因為是在 recyclerView 裡面,非常容易造成 ml,原因當然就是那個定時器有沒有在適當的時機關閉。


今天遇到的是用 timer,很多人的寫法就是在 viewHolder onBinding 的時候確認 timer 是不是 null,不是null 就先關掉然後再 new 一個新的 timer,就這樣結束了。


會產生的問題是如果今天 viewholder 不可見了,那 timer 沒關掉,timer callback 裡的 view reference 還在,就會造成 ml,所以要好好地把 timer 關掉,或是你的 fragment 畫面被銷毀了,一樣會造成上述的問題。


所以我的目標就是讓 timer 可以正確地被關閉,所以關閉的點有幾個
1. 當 viewHolder recycled 時


阿其實只有一個ㄏ


然後實作就是在 recyclerView 裡的




當 viewHolder 不可見時就會 trigger 這個 function。所以在裡面關閉 timer 很合理。


但是在 fragment 畫面被銷毀時並不會 trigger 這個 function,所以必須在 fragment 的 onViewDestory 時將該 recyclerView 的 adapter 設成 null,才會 trigger ,真棒~



沒有留言:

張貼留言