Android 关于Handler警告处理 This Handler class should be static or leaks might occur

突然发现Handler这么写会报黄色警告了,意思是Hanlder必须是static

This Handler class should be static or leaks might occur

问题分析


1.Android App启动的时候,Android Framework 为主线程创建一个Looper对象,这个Looper对象将贯穿这个App的整个生命周期,它实现了一个消息队列(Message  Queue),并且开启一个循环来处理Message对象。而Framework的主要事件都包含着内部Message对象,当这些事件被触发的时候,Message对象会被加到消息队列中执行。
2.当一个Handler被实例化时(如上面那样),它将和主线程Looper对象的消息队列相关联,被推到消息队列中的Message对象将持有一个Handler的引用以便于当Looper处理到这个Message的时候,Framework执行Handler的handleMessage(Message)方法。
3.在 Java 语言中,非静态匿名内部类将持有一个对外部类的隐式引用,而静态内部类则不会。

按如上所说,如果我们在Activity这样写的话

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);
                 
    mLeakyHandler.postDelayed(new Runnable() {
      @Override
      public void run() { }
    }, 60 * 10 * 1000);
                 
    finish();
  }
}

当Activity被finish()掉,Message 将存在于消息队列中长达10分钟的时间才会被执行到。这个Message持有一个对Handler的引用,Handler也会持有一个对于外部类(SampleActivity)的隐式引用,这些引用在Message被执行前将一直保持,这样会保证Activity的上下文不被垃圾回收机制回收,同时也会泄露应用程序的资源(views and resources)

问题解决


那么怎么样才是正确的用法呢

public class SampleActivity extends Activity {        
  private String username;
 private TextView text_username;

  private 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) {
        // ...
       text_username.setText(username);
      }
    }
  }     
  private MyHandler mHandler = new MyHandler(this);
  
  private Runnable sRunnable = new Runnable() {
      @Override
      public void run() {
        username = "123"; 
      }
  };
        
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);        
    mHandler.postDelayed(sRunnable, 60 * 10 * 1000);            
    finish();
  }
}

虽然还是非静态内部类,但hanler有了对Activity的WeakReference

你可能感兴趣的:(Android笔记)