[关闭]
@lovesosoi 2017-10-30T08:34:58.000000Z 字数 1396 阅读 1115

Handler 内存泄露分析处理和 Handler回收方式


一、Handler 内存泄露的原因

参考:http://m.myexception.cn/android/2108819.html

1.内部类的方式实例化Handler

  1. Handler handler = new Handler() {
  2. @Override
  3. public void handleMessage(Message msg) {
  4. super.handleMessage(msg);
  5. }
  6. };

这个的问题是 Java 中 成员内部类及匿名内部类都会隐式的持有外部类对象的引用,影响外部类对象的回收。GC只会回收没有被引用或者根集不可到达的对象(取决于GC算法),内部类在生命周期内始终持有外部类的对象的引用,造成外部类的对象始终不满足GC的回收条件,反映在内存上就是内存泄露。

2.生命周期和 Activity 不一样

内部类持有外部类Activity的引用,当Handler对象有Message在排队,则无法释放,进而导致Activity对象不能释放。

正确 Handler 的写法:

  1. MyHandler mhandler;
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. mhandler = new MyHandler(this);
  6. mhandler.sendEmptyMessage(0);
  7. }
  8. static class MyHandler extends Handler {
  9. private WeakReference<MainActivity> activityWeakReference;
  10. public MyHandler(MainActivity activity) {
  11. activityWeakReference = new WeakReference<MainActivity>(activity);
  12. }
  13. @Override
  14. public void handleMessage(Message msg) {
  15. super.handleMessage(msg);
  16. MainActivity act= activityWeakReference.get();
  17. if (activityWeakReference!= null && act!= null) {
  18. // ......
  19. }
  20. }
  21. }

Handler 回收方式

  1. //方式一
  2. mhandler.removeMessages(0);
  3. mhandler.removeMessages(1);
  4. mhandler.removeMessages(2);
  5. mhandler.removeCallbacks(r);
  6. //方式二
  7. @Override
  8. protected void onDestroy() {
  9. super.onDestroy();
  10. mhandler.removeCallbacksAndMessages(null);
  11. }

回收方式二官方说明

  1. Remove any pending posts of callbacks and sent messages whose obj is token . Iftoken is null, all callbacks and messages will be removed
  2. //大概意思是: 意思就是当传入的参数为null时,则移除所有的callbacks和messages,这样就有效的避免了由Handler引起的内存溢出。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注