Android handler 可能会造成内存泄露

简介: Android handler 可能会造成内存泄露Android Studio使用 Handler 时; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.

Android handler 可能会造成内存泄露

Android Studio

使用 Handler 时;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            // handle something
        }
    };

Android Studio 弹出了警告;

This Handler class should be static or leaks might occur (null) less... (Ctrl+F1)

Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue. If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follows: Declare the Handler as a static class; In the outer class, instantiate a WeakReference to the outer class and pass this object to your Handler when you instantiate the Handler; Make all references to members of the outer class using the WeakReference object. 

如果这个Handler用的是主线程外的Looper或者消息队列就没事。若是在主线程中,Handler的消息还在队列中尚未被处理,GC有可能无法回收这个Handler;也就无法回收使用这个Handler的外部类(如Activity、Service),有可能引起OOM。
换句话说,当Activity结束时,延迟的消息还可能在消息队列中。消息引用这Activity的Handler,Handler持有着它的外部类(也就是这个Activity)。这个引用会持续到消息被处理,在此之前不会被GC。
Java中,非静态内部类和匿名类会引用了它们的外部类。

根据修改建议,按照提示进行修改,将handler声明为static。

    static class rustHandler extends Handler {
        private final WeakReference<MySwipeActivity> mActivity;
 
        rustHandler(MySwipeActivity mySwipeActivity) {
            mActivity = new WeakReference<MySwipeActivity>(mySwipeActivity);
        }
 
        @Override
        public void handleMessage(Message msg) {
            MySwipeActivity activity = mActivity.get();
            if (activity != null) {
                // la la la la la ...
            }
        }
    }

静态类 rustHandler 中定义一个 WeakReference(弱引用);利用这个若引用来完成操作。这样警告就消失了。

参考Android源码,也有这种做法,没有使用弱引用的

    static class MyHandler extends Handler {
        MySwipeActivity handlerSwipeActivity;
 
        MyHandler(MySwipeActivity mySwipeActivity) {
            handlerSwipeActivity = mySwipeActivity;
        }
 
        @Override
        public void handleMessage(Message msg) {
            if (handlerSwipeActivity != null) {
                // do something
            }
        }
    }

同样消除了AS的警告;MyHandler 声明为 static,达到了目的

Java中的引用

java.lang.ref 类库包含了一组类,这些类为垃圾回收提供了更大的灵活性。
SoftReference WeakReference PhantomReference 由强到弱,对应不同级别的“可获得性”;越弱表示对垃圾回收器的限制越少,对象越容易被回收。

参考
http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html
http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler

目录
相关文章
|
2月前
|
消息中间件 存储 Java
Android消息处理机制(Handler+Looper+Message+MessageQueue)
Android消息处理机制(Handler+Looper+Message+MessageQueue)
41 2
|
2月前
|
存储 前端开发 Java
Android MVVM架构模式下如何避免内存泄漏
Android采用MVVM架构开发项目,如何避免内存泄漏风险?怎样避免内存泄漏?
96 1
|
17天前
|
Android开发 开发者
Android性能优化——内存管理的艺术
Android性能优化——内存管理的艺术
|
2月前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
|
2月前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
53 1
|
2月前
|
消息中间件 存储 Java
Android消息处理机制(Handler+Looper+Message+MessageQueue)
Android消息处理机制(Handler+Looper+Message+MessageQueue)
47 2
|
2月前
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
51 2
|
3月前
|
Java 测试技术 Android开发
Android性能测试——发现和定位内存泄露和卡顿
本文详细介绍了Android应用性能测试中的内存泄漏与卡顿问题及其解决方案。首先,文章描述了使用MAT工具定位内存泄漏的具体步骤,并通过实例展示了如何分析Histogram图表和Dominator Tree。接着,针对卡顿问题,文章探讨了其产生原因,并提供了多种测试方法,包括GPU呈现模式分析、FPS Meter软件测试、绘制圆点计数法及Android Studio自带的GPU监控功能。最后,文章给出了排查卡顿问题的四个方向,帮助开发者优化应用性能。
181 4
Android性能测试——发现和定位内存泄露和卡顿
|
4月前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android 消息处理机制估计都被写烂了,但是依然还是要写一下,因为Android应用程序是通过消息来驱动的,Android某种意义上也可以说成是一个以消息驱动的系统,UI、事件、生命周期都和消息处理机制息息相关,并且消息处理机制在整个Android知识体系中也是尤其重要,在太多的源码分析的文章讲得比较繁琐,很多人对整个消息处理机制依然是懵懵懂懂,这篇文章通过一些问答的模式结合Android主线程(UI线程)的工作原理来讲解,源码注释很全,还有结合流程图,如果你对Android 消息处理机制还不是很理解,我相信只要你静下心来耐心的看,肯定会有不少的收获的。
209 3
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
下一篇
无影云桌面