解决Android中使用ClickableSpan导致的内存泄漏

Android中TextView设置部分文字点击时需要用到ClickableSpan,但是ClickableSpan会引起内存泄漏(通过LeakCanary可以检测到),网上找了好久没看到有效地解决方案,经过尝试,解决方案如下:

在页面销毁时(比如:Activity的onDestroy、Fragment的onDestroyView、View的onDetachedFromWindow),把TextView的Spannable清空就可以了,比如我在自定义View中这样处理的,其它地方同理:

    override fun onDetachedFromWindow() {
        val c = tv.text
        if(c is Spannable) {
            c.clearSpans()
        }
        tv.text = ""
        super.onDetachedFromWindow()
    }

补充:上面示例中的代码是kotlin,使用了扩展函数,如果是java,可以这样写

    CharSequence text = tv.getText();
    if (text instanceof Spannable) {
        Spannable spannable = (Spannable) text;

        // 如果项目引入了core-ktx,依然可以使用Kotlin的扩展函数简写如下
        SpannableStringKt.clearSpans(spannable);
    
        // 如果没有引入core-ktx,可以这样写
        //Object[] spans = spannable.getSpans(0, text.length(), Object.class);
        //for (Object span: spans) {
        //    spannable.removeSpan(span);
        //}
    }

再次补充,经过一段时间的运行发现确实如评论区所说,上面的方法只是让泄漏的概率降低了很多并不能彻底解决,最终我还是采用使用非内部类的方式来解决了,即单独创建一个实现回调的类,不过仍然需要注意一点,如果实现类里面需要直接或者间接(比如用到view)引用当前页面的context,那么依然可能会发生内存泄漏,原因跟匿名内部类是一样的,解决方法很简单,就是在页面销毁时,把实现类对象里面的引用给置null即可(注意判空防止空指针)。

大概写法如下:

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值