> 文档中心 > Handler出现内存泄漏的原因,以及解决方法

Handler出现内存泄漏的原因,以及解决方法

In Android, Handler classes should be static or leaks might occur. Messages enqueued on the application thread's MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class.

大体翻译如下:

Handler 类应该应该为static类型,否则有可能造成泄露。在程序消息队列中排队的消息保持了对目标Handler类的应用。如果Handler是个内部类,那 么它也会保持它所在的外部类的引用。为了避免泄露这个外部类,应该将Handler声明为static嵌套类,并且使用对外部类的弱应用。

发生内存泄漏的情况举个例子:

private Handler mHandler1 = new Handler(){      public void handleMessage(Message msg) {  };  };  

当app启动的时候,Android Framework会为主线程创建一个Looper对象,这个Looper对象贯穿这个App的整个生命周期,它实现了一个消息队列(Message Queue),并且开启一个循环来处理Message对象,而Framework的主要事件都包含着内部Message对象,当这些事件被触发的时候,Message对象会被加到消息队列中执行。当一个Handler被实例化时,它将和主线程Looper对象的消息队列息息相关,被推倒消息队列中的Message对象将持有一个Handler的引用以便于Looper处理到这个Message的时候,Framework执行handler的handleMessage(Message)方法。

在Java 中:非静态的内部类和匿名类都会隐式的持有一份对外部类的引用,而静态的内部类则不会包含对外部类的引用。

解决这个问题最简单的方法:使用官方给的方法,

private Handler mHandler2 = new Handler(new Handler.Callback() {    @Override  public boolean handleMessage(Message msg) {      return false;  }     }); 

彭州一中