Closed mazzouzi closed 2 years ago
There should be no leak detected as I'm cleaning up "_binding" correctly in onDestroyView()
You might be doing the right thing with your bindings, but there's still a leak caused by something else. You should believe LeakCanary when it tells you there's a leak, there's nothing to fix in LeakCanary here.
From what I can tell, your app has a MaterialButton with id holding_reference_from_background_solution
(interesting name!). That button is detached and should likely be garbage collected, but it can't because there's an animator looping a ripple animation on it. You need to cancel that animator. More details: https://square.github.io/leakcanary/changelog/#objectanimator-leaks
Thank you for leading me to the root cause. I think I understand what's going on :
I'm not using any animator but MaterialButton does it internally for the ripple effect. On my app, once the user taps on a button it starts a new fragment right way and the ripple effect does not end before the fragment transaction occurs.
In the same time, I found this issue on Google Issue Tracker (reported by you maybe?) : https://issuetracker.google.com/issues/212993949
I think this is the same root cause. If a user clicks a button and the ripple effect animation does not end before the fragment is replaced then the view leaks probably because Android does not cancel the animation.
If I set a delay of 2 seconds to let the button complete its ripple animation before the fragment transaction -> the view is not leaking anymore
So that's probably an ASOP issue.
PS : to reproduce the issue, we simply need to click a button and "replace" (+ "addToBackStack") current fragment by another one =/
I did file that issue, and looking more closely now I actually think they're different issues. It looks like you might have found a core leak issue with ripple animators in AOSP.. Do you think you could create a small project with LeakCanary enabled that reproduces the issue and share it here? If this is still not fixed in the latest versions of AOSP we should file a ticket, which means we need a repro.
Thanks! I can repro on an emulator API 31 and on Android 13 DP 2 as well (had to click & hit back several times for that 2nd one though)
Thank you for testing on latest version of Android. Honestly this issue is so annoying when you have LeakCanary installed on your debug app, especially when you decrease "retainedVisibleThreshold" property to less than 5. Besides, it might confuse some people using the library for not understanding where this leak comes from. Not to mention this issue deteriorates app performance by retaining memory. If the issue is still there, we should file a ticket. I'll do it if you like or if you wanna do it, be my guest.
Filed here: https://issuetracker.google.com/issues/229136453 (sorry just saw your response)
We should also add a pattern to our db.
Note: reproduced on API 31 and API 32, but not API 29 or API 30.
Note: this bug what just marked as fixed on the Google side!
Description
Hi LeakCanary team. First of all, a big thank you for this great library !
The issue is super simple to reproduce : I run my app which displays a fragment called "MainFragment" in which I use DataBinding. When the end-user clicks on the button to display a second fragment, I replace current fragment by selected one using FragmentTransactionApi and "replace()" along with "addToBackStack()". So at this point, "MainFragment" gets its view destroyed only. Then second fragment is displayed and if I wait a couple of seconds, LeakCanary reports a leak saying that "MainFragment" view is leaking while I do set "_binding" to null in onDestroyView() :
override fun onDestroyView() { _binding = null super.onDestroyView() }
Steps to Reproduce
Sample app : https://github.com/mazzouzi/MemoryLeakApp
Expected behavior: There should be no leak detected as I'm cleaning up "_binding" correctly in onDestroyView()
Version Information
Leak Trace :
2022-04-13 12:04:24.098 16642-16724/com.mazzouzi.memoryleak D/LeakCanary: Heap dump timestamp: 1649844264045 Heap dump duration: 3191 ms