2013-03-26 83 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