DEV Community

mustHASHman
mustHASHman

Posted on

Prevent RecyclerView Leaking

If you've ever had an Adapter as a property of a Fragment, you should really stop doing that because having an Adapter as a property of a Fragment is a known way of leaking the RecyclerView. That’s because, when the View is destroyed, the RecyclerView is destroyed along with it. But if the Fragment references the Adapter, the garbage collector won’t be able to collect the RecyclerView instance because Adapters and RecyclerViews have a circular dependency. In other words, they reference each other.

If you create a method to glue together all the UI setup code (setupUI()) and inside that method, you delegate each component’s setup to other methods (createAdapter(), setupRecyclerView()), then you can be sure your adapter will be safe within setupUI()'s scope and you don't have to worry about the recyclerView leaking. It also makes your code cleaner, more organized, and it follows the single responsibility rule.

// PostFragment.kt

override fun onViewCreated( 
  view: View,
  savedInstanceState: Bundle? 
  ) {
  super.onViewCreated(view, savedInstanceState) 
  setupUI()
}

private fun setupUI() {
  val adapter = createAdapter()
  setupRecyclerView(adapter)
}

private fun createAdapter(): PostAdapter { 
  return PostAdapter()
}

private fun setupRecyclerView(postAdapter: PostAdapter) {
  binding.recyclerView.apply { 
    adapter = postAdapter
    layoutManager = GridLayoutManager(requireContext(), 
ITEMS_PER_ROW)
    setHasFixedSize(true) 
  }
}
Enter fullscreen mode Exit fullscreen mode

However, if you aboslutely need the Adapter as a property of a Fragment, then you have to remember to either:
1) Null out the Adapter property in onDestroyView.
or
2) Null out the Adapter reference in the RecyclerView itself, before doing the same for the binding.

// PostFragment.kt

//...
override fun onDestroyView() { 
  super.onDestroyView()
  // either
  adapter = null // 1

  // or
  binding.recyclerView.adapter = null // 2
  _binding = null // 2
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)