Search code examples
androidandroid-recyclerviewandroid-viewholderandroid-viewbinding

Does one need to free the viewbinding in the RecyclerView's ViewHolder to avoid memory leaks?


In Google Provided, ViewBinding example, we need to set our viewBinding to null for Fragment but not for Activity. https://developer.android.com/topic/libraries/view-binding

The reason is apparent to me, as Activity will get destroyed together with its View, but not for Fragment (Fragment live longer than its view, i.e. when the fragment is Replaced).

However, for RecyclerView, if we have the ViewBinding in the ViewHolder, like the example below (taken from https://stackoverflow.com/a/60427658/3286489), where PaymentHolder is storing a ViewBinding (i.e. itemBinding). Do we need to set it to null?

class PaymentAdapter(private val paymentList: List<PaymentBean>) : RecyclerView.Adapter<PaymentAdapter.PaymentHolder>() {
  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PaymentHolder {
    val itemBinding = RowPaymentBinding
      .inflate(LayoutInflater.from(parent.context), parent, false)
    return PaymentHolder(itemBinding)
  }
    
  override fun onBindViewHolder(holder: PaymentHolder, position: Int) {
    val paymentBean: PaymentBean = paymentList[position]
    holder.bind(paymentBean)
  }
    
  override fun getItemCount(): Int = paymentList.size
    
  class PaymentHolder(private val itemBinding: RowPaymentBinding) : RecyclerView.ViewHolder(itemBinding.root) {
  
    fun bind(paymentBean: PaymentBean) {
      itemBinding.tvPaymentInvoiceNumber.text = paymentBean.invoiceNumber
      itemBinding.tvPaymentAmount.text = paymentBean.totalAmount
    }
  }
}

My guess is that the viewBinding in ViewHolder does not need to be set to null (or released) as the viewBinding in the ViewHolder will not outlive the ViewHolder. I assume if the ViewHolder is detached from the RecyclerView, and not being used, it will be removed by the adaptor, without us needing to manually release the ViewBinding it has.

But checking here in case my understanding is incorrect.


Solution

  • The answer is NO. There's no need to release the ViewBinding in the ViewHolder.

    If we see the ViewHolder instantiation

    class PaymentHolder(private val itemBinding: RowPaymentBinding) 
    : RecyclerView.ViewHolder(itemBinding.root) { ... }
    

    We notice the View (itemBinding.root) is instantiated as part of the ViewHolder, and will live there as long as the ViewHolder is alive. Unlike Fragment, where Fragment can lives longer than the View, and the View does change within an instance of Fragment.

    Hence releasing the ViewBinding is not helping resolve the memory leak.

    More elaboration in this article