Handler 如果設(shè)置為私有變量的話,Android Studio 會報警告,提示可能會造成內(nèi)存泄漏,這種情況可以通過設(shè)置為靜態(tài)內(nèi)部類 + 弱引用,或者在onDestroy()方法中調(diào)用Handler.removeCallbacksAndMessages(null)即可避免
Handler 詳解:
一.什么是Handler
Handler是Android給我們提供用來更新UI的一套機制,是一套消息處理機制,可以通過它來發(fā)送消息和處理消息。那作為開發(fā)者的我們,不禁會疑問?Google為什么要設(shè)計這套機制呢?這是為了解決在非UI線程中更新UI組件比較麻煩的問題。那么Android為什么不能在非UI線程中更新呢?首先Android的UI控件不是線程安全的,這是因為避免多線程并發(fā)所帶來不安全問題。例如作一個假設(shè),現(xiàn)在在子線程中刷新界面,同時也在UI線程中刷新界面,就會出現(xiàn)刷新不同步,簡單來講通過Handler就可以更新UI操作切換到主線程中執(zhí)行。
二.Handler機制主要角色
Message:消息,就是一個載體,包含消息ID,消息處理對象和處理的數(shù)據(jù)等,統(tǒng)一放到MessageQueue,最終由Handler處理。
Handler:用于同一個進程的線程間通信,消息處理者,專門負責(zé)Message的發(fā)送和處理。我們使用Handler時,一般通過handleMessage(Message msg)來處理Message,也就是統(tǒng)一處理消息的回調(diào),確保自己發(fā)出的消息也是自己來處理。
MessageQueue:由名字可推出這是隊列,就是存放Handler發(fā)送過來的消息,按照先進先出的順序規(guī)則來執(zhí)行。將鏈表的數(shù)據(jù)結(jié)構(gòu)以Message來串聯(lián)起來,等待Looper的抽取,為什么需要隊列呢?因為同一線程在一個時間只能處理一個消息。因此需要隊列來保存這些消息,然后挨個挨個拿出來處理,創(chuàng)建一個線程時并不會自動創(chuàng)建MessageQueue,但是主線程創(chuàng)建時會默認創(chuàng)建Looper對象,而Looper創(chuàng)建時就會創(chuàng)建MessageQueue,其他非主線程需要looper的時候就會通過調(diào)用prepare函數(shù)來實現(xiàn)。
Looper:首先要理解一個線程是一段可執(zhí)行的代碼,作為App的主線程,不能讓代碼執(zhí)行完,因為代碼執(zhí)行完的話app就會自動退出,因此不能讓主線程不能讓代碼段執(zhí)行,只能在代碼中插入一個死循環(huán),這時候Looper的作用就體現(xiàn)出來了,將主線程變成Looper線程。并且這時主線程就會在等其他線程發(fā)消息(更新UI和Activity狀態(tài)等等)那,另外,Looper不斷從消息隊列拿出消息給主線程,也就是無限循環(huán)去查找是否有消息,有就去處理,沒有的話就一直等待,一個MessageQueue需要一個Looper。
Thread:負責(zé)調(diào)度整個消息的循環(huán)。
通過上面可以得知:Handler的作用是發(fā)送和處理消息,Handler發(fā)送的消息必須被送到指定MessageQueue中,也就是說,要讓Handler正常工作就必須有一個MessageQueue,但是MessageQueue是由Looper來抽取自身的Message,也因此當(dāng)前線程中必須有一個Looper對象。