Handler用于處理和從隊(duì)列MessageQueue中得到Message。1般我們要重寫Handler的handleMessage(Message msg){}方法來處理,以下代碼:
這個(gè)時(shí)候Handler會(huì)被Android SDK中Lint工具檢查正告你(左側(cè)那個(gè)黃色燈泡+嘆號(hào)):This Handler class should be static or leaks might occur 。
This Handler class should be static:
(知識(shí)點(diǎn)1)為何靜態(tài)內(nèi)部類可以解決這個(gè)問題呢?或說靜態(tài)內(nèi)部類和非靜態(tài)內(nèi)部類的區(qū)分是甚么?
舉例:class A{int a; static int b class B{} static class C{} } (A是外部類,B非靜態(tài)內(nèi)部類,C靜態(tài)內(nèi)部類,a普通字段,b靜態(tài)字段)
1)B非靜態(tài)內(nèi)部類:
可以訪問A.a和A.b,也就是外部的屬性都能方位。由于B隱式的持有A類對(duì)象的援用,相當(dāng)于A的屬性
2)C靜態(tài)內(nèi)部類:
C只可以訪問A.b,不可以方位A.a。為何?由于C不含有A的援用,它和A類是同1個(gè)級(jí)別,只不過寫到了A類的內(nèi)部。
本例緣由:
Handler匿名內(nèi)部類,隱式的持有了外部類Activity的援用(這就是為何你能在handleMessage()中調(diào)用MainActivity中TextView等的屬性)。--->而以后調(diào)
在100秒后message被履行,這期間message被放在MessageQueue中,MessageQueue在Looper中,Looper是線程的本地變量。
也就是說MainActivity即便生命周期走完了也不會(huì)垃圾回收,為何?由于Java的垃圾回收機(jī)制,就是看1個(gè)對(duì)象有無被援用(從線程中的主要對(duì)象開始,對(duì)象之間的援用構(gòu)成網(wǎng)狀結(jié)構(gòu),如果有類的對(duì)象不在這張網(wǎng)上,就證明它沒被援用。這就是數(shù)據(jù)結(jié)構(gòu)中圖的遍歷,甚么連通子圖,非連通子圖)。而本文中1個(gè)MainActivity被Handler持有援用,Handler被Message持有援用,Message被MessageQueue持有援用,MessageQueue被Looper持有援用,Looper為線程本地變量,線程不被摧毀,它就不會(huì)被燒毀。
所以即使用戶已切換、退出到別的Activity,MainActivity占有的內(nèi)存仍舊不會(huì)被釋放。
打破援用鏈:
1.Message在100秒后被處理,以后回收Message,然后回收MainActivity。(所以是實(shí)際上,你只要不發(fā)很長(zhǎng)時(shí)間的Message也不會(huì)有甚么問題)
2.使Handler不持有MainActivity的援用,用弱援用WeakReference:(簡(jiǎn)單講,就是只有WeakReference援用的對(duì)象,垃圾回收將回收該對(duì)象,以后再另寫1篇援用的文章吧)