随笔 - 741  文章 - 0  评论 - 260  阅读 - 416万

Android - Handler导致的内存泄漏

内存泄漏:没有用的对象,无法被GC垃圾回收,就会造成内存泄漏(OOM)

Handler如果使用不当,极大可能造成内存泄漏。比如:我们一般使用handler的方式,会在主线程中使用匿名类来创建handler:

Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };


内存泄漏的原因:
  1. 在Java 中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用,静态的内部类不会持有外部类的引用。

  2. 而由于Handler原来,MessageQueue中的Message会对Handler持有引用,而handler会对Activity持有引用,即:
    message -----> handler ----->activity

  3. 所以,当Activity被销毁时,如果MessageQueue中仍然有message没有处理完,就会一直持有对Activity的引用,导致GC无法回收Activity,由此造成内存泄漏。

两种解决方法:
  1. 将Handler定义为静态内部类,提高调用WeakReference来完成handler对Activity的弱引用。GC回收机制规定,当对象被其他对象弱引用时,允许GC对其回收。具体的代码实现:

private static class MyHandler extends Handler{
    private WeakReference<MainActivity> weakReference;
    public MyHandler(MainActivity activity){
        weakReference = new WeakReference<>(activity);
    }
    Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        final Activity activity = weakReference.get();
        if (activity != null) {
            //实现相应逻辑
        }
     }
}

2 在Activity被销毁时,将未处理的message全部remove。代码实现:
@Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeCallbacksAndMessages(null);
    }


这样使用Handler,就不会造成内存泄漏了。
posted on   莫水千流  阅读(860)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2018-05-07 Windows环境下Qwt安装和使用
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示