Handler機制
Handler 主要是用于異步消息處理,類似于輔助類,他封裝了消息的投遞 處理的接口,通常用來處理耗時較長的操作
handler中有四個重要的對象:

Looper 它的內部包含了一個消息隊列,也就是Messagequeue 所有的handler發(fā)送的消息都會進入這個消息隊列
Looper的loop方法 是一個死循環(huán)? 它不斷的從MessageQueue中來獲取消息 如果有消息就處理消息 沒有消息他就會進去阻塞狀態(tài)
Meassagequeue 就是一個消息隊列 可以添加消息并處理消息
當我們在主線程new一個Handler 的時候我們就可以使用主線程的Handler關聯(lián)到我們的looper和messagequeue當我們難道數(shù)據(jù)以后我們用handlersendmesssage方法 用looper 這個循環(huán)去得到我們的數(shù)據(jù)
Activity的生命周期也是依賴handler的消息機制來進行回調的 是在我們ActivityThread里handler 依靠 what 盡心分值 去進行不同的回調方法,從而實現(xiàn)不同的Activity的生命周期。handler 主要用于異步消息處理,Android提供給我們來更新UI的一套機制,可以通過handler來發(fā)送消息,也可以來接受并處理消息。
? 異步消息處理:? android 在設計時就分裝了這么一套機制,可以通過handler來發(fā)送消息,也可以接受并處理消息
如果不遵循這個機制就無法更新UI,就會拋出異常。為什么要通過handler機制來跟新UI呢,因為假設activity中有多個線程去更新ui ,并且沒有加鎖機制,就會產生頁面亂,如果對ui操作進行枷鎖機制的會性能會下降,所以我們使用handler 保證消息處理的先后順序。
由于Handler是運行在主線程中(UI線程中),? 而且它的設計可以使它與子線程通過Message對象來傳遞數(shù)據(jù), 這個時候,Handler就承擔著接受子線程傳過來的(子線程用sedMessage()方法傳弟)Message對象,(里面包含數(shù)據(jù))? ,把這些消息放入主線程隊列中,配合主線程進行更新UI。子線程對主線程發(fā)信息Message對象(Message包含的信息可以是int,object類型)盡可能使用Message.what來標識信息,以便用不同的方式處理Message;
執(zhí)行流程: 子線程通過sendmessage發(fā)送message消息,這個消息會被放入messageQueue隊列中,
隊列會以先進先出的方式,被Looper抽取,looper抽取到信息,交由主線程的handler,handler通過handleMessage處理信息,之后更新ui。
handler主要有
Message:消息,其中包含了消息ID,消息處理對象以及處理的數(shù)據(jù)等,由MessageQueue統(tǒng)一列隊,終由Handler處理。
Handler:處理者,負責Message的發(fā)送及處理。使用Handler時,需要實現(xiàn)handleMessage(Message msg)方法來對特定的Message進行處理,例如更新UI等。
Handler類的主要作用:(有兩個主要作用)1)、在工作線程中發(fā)送消息;2)、在主線程中獲取、并處理消息。
MessageQueue:消息隊列,用來存放Handler發(fā)送過來的消息,
并按照FIFO規(guī)則執(zhí)行。當然,存放Message并非實際意義的保存,而是將Message串聯(lián)起來的,等待Looper的抽取。
Looper:消息泵,不斷地從MessageQueue中抽取Message執(zhí)行。因此,一個MessageQueue需要一個Looper。 默認一個線程是不存在消息循環(huán)的,需要調用Looper.prepare來創(chuàng)建一個消息循環(huán),
調用Looper.loop來使消息循環(huán)起作用,當調用完loop方法后循環(huán)開始,從消息MessageQueue隊列中抽取消息,下一個由handler發(fā)送的message將會被這個handler的handleMessage處理。處理完成后調用Message.recycle將其放入Message pool中。
Thread:線程,負責調度整個消息循環(huán),即消息循環(huán)的執(zhí)行場所。
handler引起內存泄漏的原因及解決方案
如果用戶在網絡請求過程中關閉了Activity,正常情況下,Activity不再被使用,在onDestory()方法中執(zhí)行GC檢查時就應該被回收掉。
但由于這時線程尚未執(zhí)行完,而該線程持有Handler的引用(不然它怎么發(fā)消息給Handler?),
這個Handler又持有Activity的引用,就導致該Activity無法被回收,造成內存泄漏,直到網絡請求結束(圖片下載完畢)。
如果你執(zhí)行了Handler的postDelayed()方法,該方法會將你的Handler裝入一個Message,并把這條Message推到MessageQueue中,那么在你設定的delay到達之前,
會有一條MessageQueue -> Message -> Handler -> Activity的鏈,導致你的Activity被持有引用而無法被回收。
解決:靜態(tài)內部類,靜態(tài)內部類不會被當前這個類所引用,再使用弱引用,gc觸發(fā)時將handler中的activity回收。
在關閉Activity的時候停掉你的后臺線程。線程停掉了,就相當于切斷了Handler和外部連接的線,Activity自然會在合適的時候被回收。
如果你的Handler是被delay的Message持有了引用,那么使用相應的Handler的removeCallbacks()方法,把消息對象從消息隊列移除就行了。