本系列相關(guān)閱讀
Android的消息機(jī)制主要是指Handler運(yùn)行機(jī)制芽丹。由于Android開(kāi)發(fā)規(guī)范明確表示只能在主線(xiàn)程更新UI,因此當(dāng)子線(xiàn)程完成工作,我們需要使用Handler切換到主線(xiàn)程執(zhí)行UI更新操作盐股。
Handler的使用方式非常簡(jiǎn)單,我們只需要在主線(xiàn)程中創(chuàng)建Handler對(duì)象并重寫(xiě)handleMessage方法:
final SafeHandler safeHandler = new SafeHandler(this);
private static class SafeHandler extends Handler {
private WeakReference<Context> contextWeakReference;
public SafeHandler(Context context) {
this.contextWeakReference = new WeakReference<>(context);
}
@Override
public void handleMessage(Message msg) {
if (contextWeakReference != null) {
Context context = contextWeakReference.get();
if (context != null) {
//更新UI操作
switch (msg.what) {
case 0:
Toast.makeText(context, "更新UI", Toast.LENGTH_SHORT).show();
break;
case 1:
break;
default:
break;
}
}
}
super.handleMessage(msg);
}
}
然后在子線(xiàn)程中就可以發(fā)送消息提醒主線(xiàn)程更新UI:
new Thread(new Runnable() {
@Override
public void run() {
safeHandler.sendEmptyMessage(0);//子線(xiàn)程通知主線(xiàn)程更新UI
}
}).start();
Handler之所以能如此便捷地實(shí)現(xiàn)線(xiàn)程間的消息傳遞,當(dāng)然離不開(kāi)底層的MessageQueue和Looper的支持。
簡(jiǎn)單介紹一下它們:
-
MessageQueue 消息隊(duì)列
用來(lái)緩存一系列待處理的消息比吭,它的內(nèi)部存儲(chǔ)結(jié)構(gòu)并不是真正的隊(duì)列,而是采用單鏈表結(jié)構(gòu)來(lái)存儲(chǔ)消息列表姨涡。 -
Looper 循環(huán)
MessageQueue不能處理消息衩藤,這個(gè)工作由Looper來(lái)完成。它是以無(wú)限循環(huán)的形式去詢(xún)問(wèn)是否有新消息涛漂,如果有的話(huà)就處理赏表,如果沒(méi)有就一直等待。 -
ThreadLocal
一個(gè)線(xiàn)程內(nèi)部的數(shù)據(jù)存儲(chǔ)類(lèi)怖喻,通過(guò)它可以在 指定的線(xiàn)程中存儲(chǔ)數(shù)據(jù)底哗,數(shù)據(jù)存儲(chǔ)以后岁诉,只有在指定線(xiàn)程中可以獲取到存儲(chǔ)的數(shù)據(jù)锚沸,對(duì)于其他線(xiàn)程來(lái)說(shuō)則無(wú)法獲取到數(shù)據(jù)。【這是一篇詳細(xì)介紹ThreadLocal的文章涕癣,點(diǎn)擊查看】
我們知道哗蜈,Handler在創(chuàng)建的時(shí)候會(huì)采用當(dāng)前線(xiàn)程的Looper來(lái)構(gòu)建消息循環(huán)系統(tǒng),那么它是如何獲取到當(dāng)前線(xiàn)程的Looper的坠韩?答案就是使用ThreadLocal距潘,通過(guò)ThreadLocal可以輕松獲取每個(gè)線(xiàn)程的Looper。如果想繼續(xù)了解如何獲取線(xiàn)程Looper點(diǎn)擊深入理解Android消息機(jī)制(三)原理分析檀夹。
有一點(diǎn)我們要注意:線(xiàn)程在默認(rèn)情況下是沒(méi)有Looper的刃跛,如果需要使用Handler就必須為線(xiàn)程創(chuàng)建Looper穴吹,否則系統(tǒng)會(huì)拋出異常 Can't create handler inside thread that has not called Looper.prepare()
。根據(jù)我們的開(kāi)發(fā)經(jīng)驗(yàn)洞翩,Android中的主線(xiàn)程是可以直接使用Handler的稽犁,因?yàn)橄到y(tǒng)在創(chuàng)建ActivityThread的時(shí)候會(huì)為主線(xiàn)程初始化Looper。
總結(jié):本文簡(jiǎn)單地介紹一些消息機(jī)制基本概念骚亿,順帶著演示了Handler使用步驟已亥,目的就是為了讓大家對(duì)消息機(jī)制有個(gè)大致的了解,下一篇會(huì)介紹消息機(jī)制的具體流程来屠。
下一篇:深入理解Android消息機(jī)制(二)Handler工作過(guò)程
參考
- 《Android開(kāi)發(fā)藝術(shù)探索》
- http://www.reibang.com/p/f2ff9c38c5be