Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory Leak in Custom Textview with Spannable Android

I have one custom textview which has five city names and spannable click listener for each one of them. Code is as follow

/**
 * Created by @raj on 26/04/18.
 */
class TopCitiesTextView : TextView {

    private  var mListener: OnCityClickListener? = null

    constructor(ctx: Context?) : super(ctx) {
        initView(ctx, null, 0)
    }

    constructor(ctx: Context?, attrs: AttributeSet?) : super(ctx, attrs) {
        initView(ctx, attrs, 0)
    }

    constructor(ctx: Context?, attrs: AttributeSet?, defStyle: Int) : super(ctx, attrs, defStyle) {
        initView(ctx, attrs, defStyle)
    }

    private fun initView(ctx: Context?, attrs: AttributeSet?, defStyle: Int) {
    }

    override fun onFinishInflate() {
        super.onFinishInflate()
        val cityArray: Array<out String> = context.resources.getStringArray(R.array.top_cities_view_text)
        val spannableString: SpannableString = SpannableString(cityArray[0])
        this.text = spannableString
        this.append(" ")
        for (i in 1 until cityArray.size) {
            val citySpannableString = SpannableString(cityArray[i])
            citySpannableString.setSpan(object : ClickableSpan() {
                override fun onClick(widget: View?) {
                        mListener?.onCityClicked(cityArray[i])
                }
                override fun updateDrawState(ds: TextPaint) {
                    super.updateDrawState(ds)
                    ds.isUnderlineText = false
                }

            }, 0, citySpannableString.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            this.append(citySpannableString)
            if (i != cityArray.size-1)
                this.append(", ")
        }
        movementMethod = LinkMovementMethod.getInstance()
    }

    fun setCityClickListener(listener: OnCityClickListener) {
        this.mListener = listener
    }

    interface OnCityClickListener {
        fun onCityClicked(city: String?)
    }
}

But the issue is that I am getting memory leak while using this textview in fragment's layout(xml) file.

Here is the screenshot of leakcanary.

enter image description here

How to remove this memory leak?

like image 310
Raj Suvariya Avatar asked Jan 29 '26 16:01

Raj Suvariya


1 Answers

Remove the ClickableSpan from text in onDestroy of your Activity to avoid the Leak.

    if (textView.getText() instanceof SpannableString) {
          SpannableString spannableStr = (SpannableString) textView.getText();
          ClickableSpan[] spans = spannableStr.getSpans(0, spannableStr.length(), ClickableSpan.class);
          for (ClickableSpan span : spans) {
             spannableStr.removeSpan(span);
          }
          textView.setText(spannableStr);
    }
like image 165
Krishna Avatar answered Feb 01 '26 09:02

Krishna



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!