LoadingButtonAndroid icon indicating copy to clipboard operation
LoadingButtonAndroid copied to clipboard

Memory Leak when used in fragment(2.1.5 version)

Open LinasSkardzius opened this issue 5 years ago • 3 comments

Hi, CircularProgressButtonView will create memory leak in case when Activity has multiple fragments and one of Fragments implements CircularProgressButtonView. Memory leak will happen because LifecycleObserver is connected to Activity but not with a fragment that implemented it. So CircularProgressButton will have strong reference to Activity and the fragments won't release until activity is not destroyed.

LinasSkardzius avatar Jul 09 '19 06:07 LinasSkardzius

makes sense, I'll take a look at this.

leandroBorgesFerreira avatar Jul 09 '19 11:07 leandroBorgesFerreira

I created this extension method that should fix it temporary, call it in onCreateView on all your progress buttons:


import android.content.Context
import android.view.ContextThemeWrapper
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import br.com.simplepass.loadingbutton.customViews.ProgressButton

/**
 * Fixes leak, where ProgressButton is tied to the Activity's lifecycle. Issue: https://github.com/leandroBorgesFerreira/LoadingButtonAndroid/issues/144
 *
 * @param lifecycle the lifecycle to tie it to. In case of a Fragment, use the fragment view's lifecycle: [fragment.viewLifecycleOwner.lifecycle]
 */
fun ProgressButton.updateLifecycleObserver(lifecycle: Lifecycle?) {
    getContext().removeLifecycleObserver(this) // to fix the leak.
    lifecycle?.addObserver(this) // to fix leaking after the fragment's view is destroyed.
}

private fun Context.removeLifecycleObserver(observer: LifecycleObserver) {
    when (this) {
        is LifecycleOwner -> lifecycle.removeObserver(observer)
        is ContextThemeWrapper -> baseContext.removeLifecycleObserver(observer)
        is androidx.appcompat.view.ContextThemeWrapper -> baseContext.removeLifecycleObserver(observer)
    }
}

Frank1234 avatar Feb 13 '20 10:02 Frank1234

@Frank1234 solution works. Thank you for that, because we were about to get rid of this library because of RAM leakage. Your solution saved it :)

P.S. It's also applicable for 2.2.0 version.

Just for those whose don't know how to attach proper lifecycle in each of your fragments which contains circullar button you can add in onViewCreated:

nextBtn.updateLifecycleObserver(viewLifecycleOwner.lifecycle)

where nextBtn is your btn

dominik59 avatar May 11 '22 15:05 dominik59