I decided it was high time I learned how to use Leak Canary to detect Leaks within my apps, and as I always do, I tried to implement it in my project to really understand how to use the tool. Implementing it was easy enough, the difficult part was reading what the tool is throwing back at me. I have a scrollview that seems to accumulate memory in the memory manager as I scroll up and down (even though It doesnt load any new data) so I thought that was a good candidate object to track leaks on, this is the result:
It looks like v7.widget.RecyclerView is leaking the adapter, and not my application. But that can't be right.... right?
Here's the code for the adapter and the class making use of it: https://gist.github.com/feresr/a53c7b68145d6414c40ec70b3b842f1e
I started a bounty for this question because it resurfaced after two years on a completely different application
If the adapter lives any longer than the RecyclerView
does, you've got to clear the adapter reference in onDestroyView
:
@Override
public void onDestroyView() {
recyclerView.setAdapter(null);
super.onDestroyView();
}
Otherwise the adapter is going to hold a reference to the RecyclerView
which should have already gone out of memory.
Special note prior to androidx.fragment:fragment:1.3.0:
If the screen is involved in transition animations, you actually have to take this one step further and only clear the adapter when the view has become detached:
@Override
public void onDestroyView() {
recyclerView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
// no-op
}
@Override
public void onViewDetachedFromWindow(View v) {
recyclerView.setAdapter(null);
}
});
super.onDestroyView();
}
With androidx.fragment:fragment:1.3.0
and above, onDestroyView
happens after the view is detached and this extra code is no longer needed.