思考下面代碼


如果沒有仔細觀察,上面的代碼可能導緻嚴重的記憶體洩露。android lint會給出下面的警告:
in android, handler classes should be static or leaks might occur.
但是到底是洩漏,如何發生的?讓我們确定問題的根源,先寫下我們所知道的
3、在java中,非靜态的内部類和匿名類會隐式地持有一個他們外部類的引用。靜态内部類則不會。
那麼,到底是記憶體洩漏?好像很難懂,讓我們以下面的代碼作為一個例子


當這個activity被finished後,延時發送的消息會繼續在主線程的消息隊列中存活10分鐘,直到他們被處理。這個消息持有這個activity的handler引用,這個handler有隐式地持有他的外部類(在這個例子中是sampleactivity)。直到消息被處理前,這個引用都不會被釋放。是以activity不會被垃圾回收機制回收,洩露他所持有的應用程式資源。注意,第15行的匿名runnable類也一樣。匿名類的非靜态執行個體持有一個隐式的外部類引用,是以context将被洩露。
為了解決這個問題,handler的子類應該定義在一個新檔案中或使用靜态内部類。靜态内部類不會隐式持有外部類的引用。是以不會導緻它的activity洩露。如果你需要在handle内部調用外部activity的方法,那麼讓handler持有一個activity的弱引用(weakreference)以便你不會意外導緻context洩露。為了解決我們執行個體化匿名runnable類可能導緻的記憶體洩露,我們将用一個靜态變量來引用他(因為匿名類的靜态執行個體不會隐式持有他們外部類的引用)。


靜态和非靜态内部類的差別是比較難懂的,但每一個android開發人員都應該了解。開發中不能碰的雷區是什麼?不在一個activity中使用非靜态内部類, 以防它的生命周期比activity長。相反,盡量使用持有activity弱引用的靜态内部類。
<a href="http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html" target="_blank">譯文連結</a>
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
轉載:http://www.cnblogs.com/kissazi2/p/4121852.html