您好,欢迎来到二三四教育网。
搜索
您的当前位置:首页(转)Android中Handler引起的内存泄露

(转)Android中Handler引起的内存泄露

来源:二三四教育网

在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用。通常我们的代码会这样实现。


public class SampleActivity extends Activity {
 private final Handler mLeakyHandler = new Handler() { 
  @Override public void handleMessage(Message msg) {
     // ...  
    }
   }
}

但是,其实上面的代码可能导致内存泄露,当你使用Android lint工具的话,会得到这样的警告

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


public class SampleActivity extends Activity {
  private final Handler mLeakyHandler = new Handler() { 
    @Override
     public void handleMessage(Message msg) { 
        // ... 
    } 
  } 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  // Post a message and delay its execution for 10 minutes. 
  mLeakyHandler.postDelayed(new Runnable() { 
      @Override public void run() {
             /* ... */
         } 
    }, 1000 * 60 * 10); 
    // Go back to the previous 
    Activity. finish(); 
  }
}
public class SampleActivity extends Activity {

  /**
   * Instances of static inner classes do not hold an implicit
   * reference to their outer class.
   */
  private static class MyHandler extends Handler {
    private final WeakReference<SampleActivity> mActivity;

    public MyHandler(SampleActivity activity) {
      mActivity = new WeakReference<SampleActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
      SampleActivity activity = mActivity.get();
      if (activity != null) {
        // ...
      }
    }
  }

  private final MyHandler mHandler = new MyHandler(this);

  /**
   * Instances of anonymous classes do not hold an implicit
   * reference to their outer class when they are "static".
   */
  private static final Runnable sRunnable = new Runnable() {
      @Override
      public void run() { /* ... */ }
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Post a message and delay its execution for 10 minutes.
    mHandler.postDelayed(sRunnable, 1000 * 60 * 10);

    // Go back to the previous Activity.
    finish();
  }
}

其实在Android中很多的内存泄露都是由于在Activity中使用了非静态内部类导致的,就像本文提到的一样,所以当我们使用时要非静态内部类时要格外注意,如果其实例的持有对象的生命周期大于其外部类对象,那么就有可能导致内存泄露。个人倾向于使用文章的静态类和弱引用的方法解决这种问题。

Copyright © 2019- how234.cn 版权所有 赣ICP备2023008801号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务