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

Android handler 可能会造成内存泄露的更多相关文章

  1. Android 中 Handler 引起的内存泄露

    在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.其实这可能导致内存泄露,代码中哪里可能导致内存泄露,又是如何导致内存泄露的呢?那我们就慢慢分析一下.http://w ...

  2. Android中Handler引起的内存泄露

    在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. 1 2 3 4 5 6 7 8 9 public class SampleActivit ...

  3. Handler引起的内存泄露

    一般我都写handler的时候是这样的:   public class MyActivity extends Activity{ private final Handler myHandler = n ...

  4. Android 从java字节码告诉你 为什么Handler会造成内存泄露

    很多人面试的时候,都知道Handler 极易造成内存泄露,但是有一些讲不出来为什么,好一点的 会告诉你looper msg 之类的,但是你再往下问 为什么msg持有handler handler为什么 ...

  5. Android中Handler导致的内存泄露

    http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html Consider the follo ...

  6. [Android Memory] App调试内存泄露之Context篇(下)

    转载地址:http://www.cnblogs.com/qianxudetianxia/p/3655475.html 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用A ...

  7. 【转】内部Handler类引起内存泄露

    如果您在Activity中定义了一个内部Handler类,如下代码: public class MainActivity extends Activity {       private  Handl ...

  8. [Android Memory] App调试内存泄露之Context篇(上)

    转载自:http://www.cnblogs.com/qianxudetianxia/p/3645106.html Context作为最基本的上下文,承载着Activity,Service等最基本组件 ...

  9. Handler 引起的内存泄露

    先看一组简单的代码 1 2 3 4 5 6 7 8 9 public class SampleActivity extends Activity { private final Handler mHa ...

随机推荐

  1. 搭建免费wifi,嗅探接入该wifi的所有网络信息

    环境: 1: create_ap , 搭建免费wifi. 2: wireshark , 嗅探网络信息. 搭建热点 搭建热点: git clone https://github.com/oblique/ ...

  2. 【Windows 10 应用开发】如何防止应用程序被截屏

    今天老周只想跟大伙们分享一个小技巧,是的,小小的技巧,很简单,保证你能学会的,要是学不会,可以考虑跳泰山. 有些时候,我们可能会想到不要让应用程序界面上显示的内容被截屏,要阻止应用界面呈现在截图上,可 ...

  3. html5中cookie介绍,封装以及添加,获取,删除

    cookie是储存在用户本地终端上的数据. 在我们登陆网站时有记录密码,也有时间限制比如说7天,5天等等这都是我们利用cookie来写的, 这就是利用了cookie的会话周期,但cookie同时又是不 ...

  4. 【论文:麦克风阵列增强】An Algorithm For Linearly Constrained Adaptive Array Processing

    作者:桂. 时间:2017-06-03  15:06:37 链接:http://www.cnblogs.com/xingshansi/p/6937635.html 原文链接:http://pan.ba ...

  5. VirtualBox的快照功能

    VirtualBox是非常好用的一个虚拟机软件,无论是性能还是易用性不比商用的Vmware差.VirtualBox最初是Sun公司的产品,由于Sun被Oracle收购,现在也归Oracle了.除了虚拟 ...

  6. [0] WCF开发下,提示HTTP 无法注册 URL 进程不具有此命名空间的访问权限

    Visual Studio以管理员的身份运行就可以了.

  7. JS常用数据校验集合(adding)

    常用数据校验集合 var _validator = { MAIL_REGEX: /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,; ...

  8. RabbitMQ windows安装官方文档翻译!

    RabbitMQ Windows安装和配置 下载地址 官网windows下载地址: http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.10/r ...

  9. 一张图告诉你 canvas 中的 miterLimit 代表着什么

    一图胜千言, 图中有一条路径path, 沿着路径描了一条宽度为 width 的边, miterLimit 代表的是, 比例 ab/ac, 其中ac的长度为 1/2 width 来看 mdn 上的描述, ...

  10. jq和js插件的各个文件夹里放置的内容

    1. demo文件夹,存放各种实例. 2. dist文件夹,全称是distribution.在某些框架中,因为开发和发布的内容或者代码形式是不一样的(比如利用Grunt压缩等等),这时候就需要一个存放 ...