Fix ViewPager2 ‘s Memory Leak by Lifecycle-Aware Component

There is a common memory-leak issue of ViewPager2, for example, through a large or unknown number of fragments, use FragmentStateAdapter with ViewPager2, and then navigate forward to a new fragment, Leak Canary detects memory leaks.

Most of the solutions from Stack Overflow would set the adapter to null when onDestroyView():

override fun onDestroyView() {
mediator?.detach()
mediator = null
binding.viewpager.adapter = null
_binding = null

super.onDestroyView()
}
set the ViewPager adapter to null inside onDestroyView

It’s a good solution but still someones said it clears most memory leaks, but some are still retained. And most importantly, this solution didn’t benefit from Lifecycle-Aware Components.

Recommend Solutions

Another solution (that one I prefer) to prevent memory leaks with ViewPager2 inside a fragment is to use viewLifeCycleOwner when creating the FragmentStateAdapter.

FragmentStateAdapter has 3 constructors:

FragmentStateAdapter(FragmentActivity fragmentActivity)
FragmentStateAdapter(Fragment fragment)
FragmentStateAdapter(FragmentManager fragmentManager, Lifecycle lifecycle)

The first one and second one will use fragmentActivity.getLifecycle() and fragment.getLifecycle() to observe the LifecycleEvent, so previous memory leak happens. We can use the 3rd one which pass fragment’s viewLifeCycleOwner to be 2nd parameter,

val fragmentAdapter = FragmentStateAdapter(
childFragmentManager
,
viewLifecycleOwner.lifecycle)

Lead Android & iOS Mobile Engineer at Yahoo (Verizon Media) Taiwan https://www.linkedin.com/in/hanruyeh/