一缚甩、Android為什么提供Handler消息機制
在Android中不允許子線程訪問UI窑邦,Handler可以解決這個矛盾
因為Android的UI控件不是線程安全,如果并發(fā)訪問必然會產(chǎn)生不可預(yù)期的狀態(tài)冈钦。
Handler的主要作用就是將一個任務(wù)切換到指定線程中去執(zhí)行,使用Handler我們就可以把訪問UI的任務(wù)切換到主線程
二瞧筛、簡述Handler的工作原理
- Handler的運行需要底層MessagQueue和Looper的支撐,
- MessagQueue:消息隊列庆猫。采用單鏈表的數(shù)據(jù)結(jié)構(gòu)儲存消息列表
- Looper:消息循環(huán)。以無限循環(huán)的形式去查找是否有新消息月培,有就處理消息嘁字,沒有就等待著
- 線程是默認(rèn)沒有Looper的杉畜,要使用Handler必須要為線程創(chuàng)建Looper
UI線程即ActivityThread,默認(rèn)可以使用Handler此叠。因為ActivityThread被創(chuàng)建時初始化了Looper
- 那么Handler內(nèi)部如何獲取當(dāng)前線程的Looper呢?這時候就要使用ThreadLocal
ThreadLocal的作用:在每個線程中儲存數(shù)據(jù)
ThreadLocal可以在不同的線程中互不干擾的儲存并提供數(shù)據(jù)猬错,通過ThreadLocal可以輕松獲取每個線程的Looper
- Handler循環(huán)系統(tǒng)創(chuàng)建完畢后茸歧,Handler倦炒、MessageQueue、Looper就可以協(xié)同工作了逢唤。通過Handler的send方法將一個Runnable投遞到Looper中去處理
- 當(dāng)send方法被調(diào)用時涤浇,它會調(diào)用MessageQueue的enqueueMessage方法將這個消息放在消息隊列中
- Looper發(fā)現(xiàn)有新消息鳖藕,就進行處理只锭,最終消息中的Runnable或Handler的handleMessage方法被調(diào)用
- 由于Looper運行在創(chuàng)建Handler的線程中,所以Handler中的業(yè)務(wù)邏輯就被切換到Looper所在的線程中執(zhí)行了