IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 官方推荐handler的正确用法,避免内存泄漏 -> 正文阅读

[移动开发]官方推荐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,或者是在修改一些老代码的时候更不可避免,因此感觉还是一个必备要学习的东西。所以在这里总结记录下。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-07-03 10:57:45  更:2022-07-03 10:58:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 3:04:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码