Android handler 可能会造成内存泄露

Android Studio

使用 Handler 时;

    private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            // handle something        }    };

Android Studio 弹出了警告;

This Handler class should be static or leaks might occur (null) less... (Ctrl+F1)Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue. If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follows: Declare the Handler as a static class; In the outer class, instantiate a WeakReference to the outer class and pass this object to your Handler when you instantiate the Handler; Make all references to members of the outer class using the WeakReference object. 

如果这个Handler用的是主线程外的Looper或者消息队列就没事。若是在主线程中,Handler的消息还在队列中尚未被处理,GC有可能无法回收这个Handler;也就无法回收使用这个Handler的外部类(如Activity、Service),有可能引起OOM。
换句话说,当Activity结束时,延迟的消息还可能在消息队列中。消息引用这Activity的Handler,Handler持有着它的外部类(也就是这个Activity)。这个引用会持续到消息被处理,在此之前不会被GC。
Java中,非静态内部类和匿名类会引用了它们的外部类。

根据修改建议,按照提示进行修改,将handler声明为static。

    static class rustHandler extends Handler {        private final WeakReference<MySwipeActivity> mActivity;         rustHandler(MySwipeActivity mySwipeActivity) {            mActivity = new WeakReference<MySwipeActivity>(mySwipeActivity);        }         @Override        public void handleMessage(Message msg) {            MySwipeActivity activity = mActivity.get();            if (activity != null) {                // la la la la la ...            }        }    }

静态类 rustHandler 中定义一个 WeakReference(弱引用);利用这个若引用来完成操作。这样警告就消失了。

参考Android源码,也有这种做法,没有使用弱引用的

    static class MyHandler extends Handler {        MySwipeActivity handlerSwipeActivity;         MyHandler(MySwipeActivity mySwipeActivity) {            handlerSwipeActivity = mySwipeActivity;        }         @Override        public void handleMessage(Message msg) {            if (handlerSwipeActivity != null) {                // do something            }        }    }

同样消除了AS的警告;MyHandler 声明为 static,达到了目的

Java中的引用

java.lang.ref 类库包含了一组类,这些类为垃圾回收提供了更大的灵活性。
SoftReference WeakReference PhantomReference 由强到弱,对应不同级别的“可获得性”;越弱表示对垃圾回收器的限制越少,对象越容易被回收。

参考
http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html
http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler

更多相关文章

  1. Android(安卓)Resource介绍和使用
  2. 浅析Android中的消息机制-解决:Only the original thread that cr
  3. Android异步消息机制之Handler
  4. Android开发之消息处理机制(一)——Handler
  5. SlidingMenu和ActionBarSherlock结合做出出色的App布局,Facebook
  6. Android(安卓)如何开发 Bottom Navigation 风格
  7. Titanium 使用刘明星的Jpush module做android端的消息推送
  8. Android空引用问题的解决方法——on a null object reference
  9. 理解Android中垃圾回收日志信息

随机推荐

  1. Android:TextView文字跑马灯的效果实现
  2. (转)为什么Android不是GPL许可证?
  3. android 抽屉式滑动demo
  4. android button多状态, selector
  5. 修改ScrollView滚动条样式
  6. Android Studio Toast/Notification中文
  7. Android Overview
  8. Android的Adapter与BaseAdapter的介绍
  9. Android 控件属性
  10. Android练习——Spinner二级联动_城市选