您现在的位置是:百科 >>正文

androidhandler内存泄漏

百科22485人已围观

简介写Android代码,Handler这关谁都绕不过去。但用不好它,内存泄漏就是分分钟的事。我见过一个项目,退出Activity后内存死活降不下来,用MAT一查,好家伙,一个Handler死死拽着Act ...

写Android代码,内存Handler这关谁都绕不过去。泄漏但用不好它,内存内存泄漏就是泄漏分分钟的事。我见过一个项目,内存退出Activity后内存死活降不下来,泄漏用MAT一查,内存好家伙,泄漏一个Handler死死拽着Activity不放。内存

问题出在哪儿?泄漏Handler、Looper、内存MessageQueue这三兄弟是泄漏绑在一起的。主线程的内存Looper生命周期跟应用一样长,你new一个Handler,泄漏它默认就绑在主线程的内存Looper上。当你往MessageQueue里扔一个延迟消息,这个Message就会持有Handler的引用,Handler如果是非静态内部类,又隐式持有外部类(通常是Activity)的引用。链条就成了:MessageQueue -> Message -> Handler -> Activity。只要消息没执行完,Activity就别想被回收。

最典型的场景:在Activity里写个handler.postDelayed(runnable, 60000),用户打开这个页面两秒就退出了。那个Runnable还躺在消息队列里等一分钟。这一分钟里,Activity实例一直活着。如果这个Activity占了几十兆的Bitmap,内存压力直接拉满。

有人会说,那我用handler.removeCallbacksAndMessages(null)不就行了?对,这是必须做的。在onDestroy()里清掉所有消息和回调。但很多人忘了,或者压根不知道。更隐蔽的是,有些第三方库内部用了Handler,你没法控制它什么时候清理。我就遇到过某个图片加载库,内部Handler持有Context导致泄漏,最后只能换成弱引用方案。

弱引用怎么搞?把Handler改成静态内部类,然后对Activity持弱引用。这样即使消息没执行,GC也能把Activity收走。代码大概长这样:

private static class SafeHandler extends Handler {  private final WeakReference<MainActivity> mActivityRef; SafeHandler(MainActivity activity) {  mActivityRef = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) {  MainActivity activity = mActivityRef.get(); if (activity == null || activity.isFinishing()) {  return; } // 正常处理消息 } } 

静态内部类不持有外部类引用,弱引用又不会阻止GC。双保险。但注意,弱引用可能在消息执行前就被清了,所以get()之后必须判空。有人图省事直接用activity.isFinishing(),结果activity已经是null了,直接NPE崩溃。

还有个坑:HandlerThread。用完之后不调用quitSafely()或者quit(),线程一直活着,里面的Looper和MessageQueue也一直活着。如果这个HandlerThread里又持有了一些Context,照样泄漏。我见过一个日志模块,每次初始化都new一个HandlerThread,从来不退出。跑一天下来,几十个线程在那挂着,内存不炸才怪。

说到底,Handler内存泄漏的本质就一句话:长生命周期的对象持有了短生命周期对象的引用。MessageQueue是长命的,Activity是短命的,中间靠Handler和Message搭了桥。把桥拆了——要么清消息,要么断引用——问题就解决了。

实际开发中,我建议直接上Lifecycle或者ViewModel配合LiveData,从根上避开手动管理Handler的麻烦。但如果维护老代码,或者必须用Handler,那就老老实实:静态内部类 + 弱引用 + onDestroy清理。三件套少一件都可能翻车。

最后提一嘴,LeakCanary装上,别等OOM了才去查。那玩意儿一报警,基本就是实锤。我现在的项目里,LeakCanary一响,不管多忙都得先把它灭了。内存泄漏这种事,攒着攒着就成雪崩了。

Tags:

上一篇:襄阳人才网

下一篇:php列表下折叠显示

相关文章

  • ai工具是什么

    百科

    我电脑里装着一个叫“Claude”的AI工具,每天用它整理会议纪要、写邮件草稿、甚至帮我妈翻译菜谱。但你要问我它到底是什么,我的回答可能跟你想的不太一样——它不是搜索引擎的升级版,也不是什么聊天机器人 ...

    【百科】

    阅读更多
  • 苹果手机有锁无锁查询

    百科

    买iPhone的人,十有八九都听过“有锁”“无锁”这两个词。但真问起来,不少人一脸懵——锁是啥?锁谁?锁门吗?简单说,“有锁”指的是这台手机被运营商绑定了网络,只能插这家运营商的卡。比如美版ATT、日 ...

    【百科】

    阅读更多
  • 路由器检测工具

    百科

    办公室老张的路由器又卡了。他蹲在机柜边上,手机连着Wi-Fi,网页转圈转到天荒地老。我递过去一个U盘,里面装了个绿色小软件,双击运行,三秒钟后屏幕上跳出二十来个设备名——其中有个叫“iPhone-13 ...

    【百科】

    阅读更多


友情链接