引言:
- Android應(yīng)用啟動時汽抚,會默認(rèn)有一個主線程(ui線程)奶陈,在這個線程中會關(guān)聯(lián)一個消息隊(duì)列(MessageQueue),所有的操作都會被封裝成消息(Message)然后交給主線程處理 ,為了保證主線程不會主動退出易阳,會將消息的操作放在一個死循環(huán)中煤杀,這樣程序就相當(dāng)于一直在執(zhí)行死循環(huán)钮追,因此不會退出晃财。
-
對于主線程來說,會自動綁定一個消息循環(huán)looper,查看源碼建炫,如圖畦韭,主線程的消息循環(huán)在main方法(android程序的入口)中已經(jīng)被創(chuàng)建。
ActivityThread.main方法執(zhí)行完肛跌,應(yīng)用程序就啟動了艺配,系統(tǒng)將消息投遞到消息隊(duì)列中据过,又會從消息隊(duì)列中獲取消息并且處理消息,而這一切Handler
起著重要的作用~
重點(diǎn)理解:
- 在主線程中創(chuàng)建妒挎,我們經(jīng)常會遇到的一個問題就是更新ui,大家都應(yīng)該知道在子線程是不能更新UI的西饵,所以我們最常見的使用手段就是通過handler將消息send回主線程酝掩,handler再通過handleMessage方法在主線程進(jìn)行處理。
class MyHandler extends Handler{
@Override
public void handleMessage(Message msg){
//更新ui---主線程
}
}
MyHandler mHandler=new MyHandler();
//新線程
new Thread(){
public void run(){
//耗時操作
mHandler.sendEmptyMessage(123);
}
}.start();
- Handler就是一個消息處理器眷柔,將消息投遞給消息隊(duì)列期虾,然后再由對應(yīng)的線程從消息隊(duì)列中逐個取出消息。
- 消息隊(duì)列是通過Looper與線程關(guān)聯(lián)
Handler的構(gòu)造函數(shù)中獲取looper驯嘱,與looper綁定镶苞,而queue封裝在looper中,通過mQueue=mLooper.mQueue鞠评;//即可獲得消息隊(duì)列
prepareMainLooper()這個方法調(diào)用prepare(這個方法中創(chuàng)建了一個looper對象)茂蚓,而prepareMainLooper()是為ui線程設(shè)置對應(yīng)的looper,這樣looper就與線程關(guān)聯(lián)上了剃幌,同理消息隊(duì)列也與線程關(guān)聯(lián)聋涨。handler也與線程關(guān)聯(lián)。
- 每一個handler都會關(guān)聯(lián)一個消息隊(duì)列负乡,handler與looper綁定牍白,而消息隊(duì)列被封裝在looper中,每一個looper又會關(guān)聯(lián)一個線程抖棘,他們之間的關(guān)系是Handler(N):Looper(1):MeaasgeQueue(1):Thread(1)
- 對應(yīng)looper:有兩個重要的點(diǎn):
Looper.prepare();//創(chuàng)建looper對象
looper獲得后茂腥,通過Looper.loop()執(zhí)行消息循環(huán) - 過程敘述
- 實(shí)例化looper:如果handler在主線程創(chuàng)建,那么主線程會默認(rèn)與其綁定一個looper和與之對應(yīng)的消息隊(duì)列切省,不用實(shí)例化looper最岗;而如果handler在子線程創(chuàng)建,android系統(tǒng)默認(rèn)情況下非主線程是沒有開啟looper的数尿,所以需要我們手動初始化looper:Looper.prepare();
- 實(shí)例化Handler handler=new Handler();
- 執(zhí)行消息循環(huán):Looper.loop()仑性。
- 實(shí)例化Message:有兩種消息類型(message,runnable)右蹦,通過handler的sendMessage(message)和post(runnable)發(fā)送消息诊杆。然后將消息壓入到消息隊(duì)列中。
-
Looper輪詢消息何陆,并調(diào)用handler.handleMeaasge()來讓handler處理消息晨汹。
根據(jù)上圖可以總結(jié)一個結(jié)論:
android中通過Handler機(jī)制來異步處理多線程之間的通信,就是多個線程之間共享一個MessageQueue