2013-03-26 86 views
0

据我所知,处理程序可以在Android的内存泄漏,但我不是很确定我所做的是正确的:Android处理程序,内存泄漏?

public class MyActivity extends Activity 
{ 

Handler handler; 
HashMap<String, String> bigData = new HashMap<String, String>(); 

protected void onCreate(undle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    handler = new WeakHandler(){ 
     public void handlerMessage(Message msg, Context conetxt) 
     { 
      // i think this usage is wrong, still leak, am I right? 
      Log.v("MyActivity", bigData.get("abc")) 
     } 
    } 
}; 


static class WeakHandler extends Handler { 

    private final WeakReference<Context> ref; 

    public WeakHandler(Context t) { 
     super(); 
     ref = new WeakReference<Context>(t); 
    } 

    @Override 
    public final void handleMessage(Message msg) { 
     final Context context = ref.get(); 
     if (context != null) { 
      handleMessage(msg, context); 
     } 
    } 

    public void handlerMessage(Message msg, Context conetxt) 
    { 

    } 

} 

而且,如果我只想用一个处理程序“后”,“postDelayed” “removeCallbacks”,我不关心的handleMessage,是安全的,只需要创建一个新的处理程序实例要做到这一点,就像这样:

new Handler().postDelayed(some Runnable); 
+0

参考[这里](http://v4all123.blogspot.com/2012/12/handler.html)处理器帮助在android – Gunaseelan 2013-03-26 06:01:12

回答

1

当你实例化WeakHandler时,它不会是一个实际的WeakHandler类,而是一个扩展了WeakHandler类的Anonymous类。 Anonymous类永远不会是静态的,所以除了显式的WeakReference外,它还会隐式引用包含的类(即MyActivity)。由于onCreate()在主线程上运行,因此在onCreate()内部创建的Handler将与主要花纹(实际上是应用程序启动时创建的主Looper)相关联。如果您发布消息(或Runnable,因为Runnable将被消息包装)给Handler,那么Message/Runnable将会引用Handler。

因此,给你postL延迟5分钟的东西。在销毁Activity之后(例如由于旋转),主Looper将引用Message/Runnable,Message/Runnable将引用Handler,Handler将引用该Activity至5分钟。这是一个泄漏。

是的,“Log.v(”MyActivity“,bigData.get(”abc“))”行也会泄漏该活动。

+0

我相信你的解释是不正确的。其实,原来问题所做的是正确的。因为WeakHandler是一个静态的内部类,所以它不会通过对父类的隐式引用来实例化。使用静态类和弱引用的原始问题方法实际上是解决泄漏处理程序的推荐方法http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html。 – Sogger 2015-01-07 17:50:44

+0

WeakHandler是静态的,但是在onCreate中,WeakHandler类被扩展并且新的(非静态的)匿名类被声明并实例化。这样,匿名类就具有对上下文的引用。如果这行是'handler = new WeakHandler(this);'(注意,没有额外的括号来声明一个新的类),你会是对的。 – 2015-01-08 14:30:00

+0

是的,这是正确的,我似乎忽视了匿名类的创建。感谢您的更正! – Sogger 2015-01-13 16:26:58