自定义 Handler 时如何有效地避免内存泄漏问题?

 Android在自定义Handler的时候如何有效的避免内存泄漏呢?

我们首先看下普通的写法

public class MainActivity extends BaseUIActivity {
   private String a;
   Handler handler = new Handler(){
      @Override
      public void handleMessage(Message msg) {
         super.handleMessage(msg);
      }
   };

因为在java中非静态内部类和内部类会持有一个外部类的引用(这就是你为什么在内部类中可以用外部类对象的一些属性),而Handler常被用来做延迟操作,这就形成了一个典型的生命周期较长的组件持有一个生命周期较短的组件的引用,导致生命周期较短的组件无法销毁,这就造成了内存的泄漏。

如何解决呢?

  • 保证Activity被finish()时该线程的消息队列没有这个Activity的handler内部类的引用。这个场景是及其常见的,因为handler经常被用来发延时消息。一个补救的办法就是在该类需要回收的时候,手动地把消息队列中的消息清空:mHandler.removeCallbacksAndMessages(null);让handler销毁
  • Handler 用static修饰下,这样Handler就不持有外部类的引用了。(这个方法为了能调用外部类的资源,一般会传递一个外部类的弱引用进来)

第一种方法:

以Activity为列

Handler handler = new Handler(){
   @Override
   public void handleMessage(Message msg) {
      super.handleMessage(msg);
   }
};
@Override
protected void onDestroy() {
   handler.removeCallbacksAndMessages(null);
   handler = null;
   super.onDestroy();
}

第二种方法:

public class MainActivity extends BaseUIActivity {
   private String a;
   private static WeakReference<MainActivity> mmainActivity;  //创建一个MainActivity的弱引用,GCy运行的时候只要除了这    个没有别的引用,改对象就会销毁
   
   static class MyHandler extends Handler {
      public void myHandler(MainActivity mainActivity) {
         mmainActivity = new WeakReference<>(mainActivity);
      }
      
      @Override
      public void handleMessage(Message msg) {
         super.handleMessage(msg);
         MainActivity mainActivity = mmainActivity.get();  //拿到外部类的引用
      }
   }

总结:

根据上面的两种方法,我比较中意第一种,因为这个至少知道你的代码在什么时候销毁,而不是等在GC去回收

猜你喜欢

转载自blog.csdn.net/xueyoubangbang/article/details/89925149
今日推荐