官方推荐handler的正确用法,避免内存泄漏

今天在看谷歌Android公众号的文档时看到了handler关于内存泄漏方面的文章,感觉可以转载归纳一下,做一下记录。
官方公众号链接:一次性讲清楚 Handler 可能导致的内存泄漏和解决办法 | 开发者说·DTalk

首先,先说下常用的会造成泄漏的用法,直接使用内部类或者匿名内部类的方式,创建、使用Handler:


// 匿名内部类
override fun onCreate(savedInstanceState: Bundle?) {
    ...
    val innerHandler: Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            ...
        }
    }
}

// 内部类
override fun onCreate(savedInstanceState: Bundle?) {
    ...
    val innerHandler: Handler = MyHandler(Looper.getMainLooper())
}

inner class MyHandler(looper: Looper): Handler(looper) {
    override fun handleMessage(msg: Message) {
        ...
    }
}

这样创建的话,当页面退出的时候,
1、对应的线程仍在处理中、活跃

2、线程(Thread)结束,但是消息(Message)仍存在队列中,或者正在处理中,比如在handlerMessage中,
在这样的两种情况下,会造成内存泄漏。

具体大篇幅的原因可以在给出的文章中查看,总的来说,是因为使用匿名内部类调用Handler,在Activity 销毁的时候,Activity的引用仍然存在,因此造成了内存泄漏。
无论是线程(Thread >handler>activity)还是Looper(looper>messageQueue>message>handler>activity),或者是其他的方式,解决的方法,其实就是阻断这个引用链,可以采用弱引用的方式来处理,即这里推荐的使用handler的方式。
1、将Handler定义为静态内部类:

  private class MainHandler(looper: Looper?, referencedObject: MainActivity?) :
        WeakReferenceHandler<MainActivity?>(looper, referencedObject) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            val activity:MainActivity? = referencedObject
            if (activity != null){}
        }
    }

2、弱引用外部类的实例:

open class WeakReferenceHandler<T>(looper: Looper?, referencedObject: T) : Handler(looper!!) {
    private val mReference: WeakReference<T> = WeakReference(referencedObject)

    protected val referencedObject: T?
        get() = mReference.get()
}

3、使用
 

 private val mainHandler:MainHandler = MainHandler(mainLooper,this)

4、onDestroy的时候切断引用链,纠正生命周期

 override fun onDestroy() {
        super.onDestroy()
        //清空主线程Handler中未处理的消息
        mainHandler.removeCallbacksAndMessages(null)
    }

如果子线程未结束,需要中断:thread.interrupt(),如果子线程创建的looper并成为Looper线程,需手动quit:handlerThread.quitSafely()

完毕!!!

虽然感觉目前Handler的使用目前在减少,但是Handler的机制在面试中还是热门话题,以及有时候仍然会使用到Handler,或者是在修改一些老代码的时候更不可避免,因此感觉还是一个必备要学习的东西。所以在这里总结记录下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值