Handler的内存泄漏问题

后台线程任务处理完成后,常用Handler来更新ui事件,常用代码如下:

private Handler handler = new Handler()
{
      public void handleMessage(android.os.Message msg)
   {
          if (msg.what == 1) {
                listAdapter.notifyDataSetChanged();
          }
     }
 };

这段代码可能造成内存泄漏,原因是:Handler作为Activity的内部类创建时,隐式持有了外部类Activity的引用。而Handler一般会伴随一个耗时的后台线程(如网络下载图片),当后台线程执行完毕时,通过handler来更新界面。但如果在网络请求的过程中关闭了Activity,此时线程尚未执行完,而该线程持有handler的引用,handler又持有外部Activity的引用,导致该Activity无法被内存回收,直到网络请求结束。

类似的使用Hanlder.postDelayed方法,Message对象持有当前handler的引用,而Message又存放在MessageQueue中,那么在dalay到达之前,一直会持有外部Activity的引用,导致内存无法回收。

为了避免Handler引起的内存泄漏,可以使用一下几种方法

一、程序保护

1)在Activity关闭前,停止后台线程;
2)在Activity关闭前,删除所有的待处理message。

//  If null, all callbacks and messages will be removed.  
mHandler.removeCallbacksAndMessages(null);  
二、静态内部类

在Java 中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用,静态的内部类不会持有外部类的引用。
可以使用弱引用来操作Activity中的对象。

static class StaicHandler extends Handler { 
    WeakReference mWeakReference; 

    public StaicHandler (Activity activity) {
        mWeakReference = new WeakReference(activity); 
    }

    @Override
    public void handleMessage(Message msg) { 
        Activity activity = mWeakReference.get(); 
        if(activity != null) { 
            if (msg.what == 1) { 
                activity.***
            } 
        } 
    } 
}

你可能感兴趣的:(Handler的内存泄漏问题)