Handler在Android開發(fā)中使用頻率還是很高的,本文主要結(jié)合自己的理解偶垮,從Handler的作用浪规,使用方式以及工作流程上分析Handler凰兑,對(duì)Handler有個(gè)整體認(rèn)識(shí)招刹,后續(xù)會(huì)再寫一篇從源碼分析Handler的原理恬试。
Handler的作用
線程間通信,這就是Handler的主要作用疯暑⊥妫或者我覺得更容易理解的說法是線程切換,因?yàn)槠綍r(shí)我們用的最多的場(chǎng)景就是在子線程獲取數(shù)據(jù)缰儿,然后利用Handler將數(shù)據(jù)發(fā)送到主線程進(jìn)行UI更新,就像是從子線程切換到主線程進(jìn)行操作散址。
Handler的使用
Handler一般有兩種使用方式:
1. 繼承Handler乖阵,實(shí)現(xiàn)handleMessage方法
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MSG1:
Log.i(TAG,"handler:"+msg.obj);
break;
}
}
};
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = Message.obtain();
msg.what = MSG1;
msg.obj = "子線程發(fā)來的消息";
mHandler.sendMessage(msg);
}
}).start();
運(yùn)行結(jié)果:
I/mainActivity: handler:子線程發(fā)來的消息
運(yùn)行成功將開啟的子線程中的消息發(fā)送到了主線程中(上面寫法在IDE中會(huì)給出警告,提示會(huì)出現(xiàn)內(nèi)存泄漏预麸,這個(gè)在后面也會(huì)再寫一篇文章記錄分析一下)
- Handler.post方式
private Handler mHandler = new Handler();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
final String result = "子線程的數(shù)據(jù)";
mHandler.post(new Runnable() {
@Override
public void run() {
boolean isMainThread = Looper.myLooper()==Looper.getMainLooper();
Log.i(TAG,"isMainThread:"+isMainThread);
Log.i(TAG,"msg:"+result);
}
});
}
}).start();
運(yùn)行結(jié)果
I/mainActivity: isMainThread:true
I/mainActivity: msg:子線程的數(shù)據(jù)
從結(jié)論看也實(shí)現(xiàn)了消息從子線程發(fā)送到主線程處理
Handler工作流程
Handler完成線程間通信主要需要四部分協(xié)作完成瞪浸,分別是Handler(處理者),Message(消息載體)吏祸,MessageQueue(消息隊(duì)列)对蒲,Looper(循環(huán)器)。
- Message為消息載體,即把需要在線程間發(fā)送的消息封裝在Message對(duì)象中
- MessageQueue為消息隊(duì)列蹈矮,是存放Message對(duì)象的地方砰逻,它是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)
- Looper是一個(gè)循環(huán)器,他是跟線程緊密相關(guān)的泛鸟,他一直在循環(huán)查詢MessageQueue中是否有數(shù)據(jù)蝠咆,有的話取出交給相應(yīng)Handler處理
- Handler為處理者,一方面是將需要傳遞的消息發(fā)送到MessageQueue中北滥,另一方面是處理Looper從MessageQueue中取出的消息刚操。
這幾個(gè)還有線程之間的關(guān)系開始學(xué)可能會(huì)比較混亂,我按照自己的理解簡(jiǎn)單總結(jié)下:
一個(gè)線程只能有一個(gè)Looper再芋,一個(gè)Looper對(duì)應(yīng)一個(gè)MessageQueue菊霜,都是一一對(duì)應(yīng)的關(guān)系
另外一個(gè)Looper可以被多個(gè)Handler綁定,而Handler處理消息的線程是綁定的Looper所對(duì)應(yīng)的線程
先對(duì)Handler及相關(guān)的一些概念有個(gè)整體印象济赎,下一篇文章會(huì)從源碼分析這幾部分具體是怎么協(xié)作實(shí)現(xiàn)線程通信的