標籤:android style color ar 使用 strong sp 資料 on
一:handler,looper,message,messagequeue,thread
handler: 訊息處理著,負責Message訊息的發送(handler.sendMessage(....))以及處理訊息,對於handler處理訊息則需要實現handlerMessage(Message msg)該方法,通過該方法處理特定的訊息,例如ui的更細
looper:訊息泵,用來從messageQueue中抽取訊息,所以一個looper對應一個messageQueue;
message:訊息,message中含有該訊息的ID以及訊息處理對象或者處理的資料,通過messageQueue訊息佇列同一處理。
messageQueue,訊息佇列,messageQueue中儲存 通過handler發送來的訊息,當然該儲存不是真正意義上儲存,而是以鏈式結構將訊息連結起來。等待looper的抽取
thread:線程,負的調度整個訊息迴圈,即訊息迴圈的場所執行
二:handler、looper、messageQueue之間的關係
looper與messageQueue是一一對應的關係,及建立一個looper的同時建立一個messageQueue,handler與它們只是簡單的彙總關係,handler中會引用當前線程中的looper與messageQueue,從這裡可以看出對個handler 能夠同時處理一個looper與messageQueue,前提是這些handler都在同一個線程中
三:簡單一實例:
訊息的產生:
Message msg=Handler.obtiainMessage();
msg.what=what;
msg.sendToTarget();
訊息發送:
MessageQueue queue=looper.myQueue();
//通過該對象找到與之對應的訊息佇列messageQueue
if(queue!=null){
msg.target=this
sent = queue.enqueueMessage(msg, uptimeMillis);
}
註:在handler的sendMessageAtTme(Message msg,long time)中可以看出handler 找到自己線程中的MessageQueue中的message 然後將message的target設定為handler自己,目的是message能夠找到正確的handler。
三:抽取
//得到handler所線上程中的looper對象;
Looper looper=handler1.getLooper();
//通過該對象找到與之對應的訊息佇列messageQueue
MessageQueue queue=looper.myQueue();
while (true) {
Message msg = queue.next(); //不斷的從訊息佇列中擷取訊息
if (msg != null) {
if (msg.target == null) {
return;
}
msg.target.dispatchMessage(msg);
msg.recycle();
}
}
從這裡我們可以看出 不斷的從訊息佇列中擷取訊息,然後通過message的target中攜帶的資訊去,尋找正確的handler 用來處理該訊息
四:處理:
handler = new Handler(){
複寫handlerMessage(Message msg);
}
至此,我們看到,一個Message經由Handler的發送,MessageQueue的入隊,Looper的抽取,又再一次地回到Handler的懷抱。而繞的這一圈,也正好協助我們將同步操作變成了非同步作業。
小執行個體:跟新UI
首先在主線程中如果我們使用handler不建立looper對象,則系統會預設使用主線程中已經建立好的looper對象,然而在非ui線程中我們使用handler而不傳入looper對象,則這個handler不能接受訊息。
通常的做法是:
Thread thread = new Thread() {
@Override
public void run() {
//建立handler之前我們需要首先準備一個looper
Looper.prepare();
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
}
};
super.run();
}
};
//將該looper啟動(跑起來)這樣就能夠從messageQueue中抽取message 這樣handler才能正常運行
Looper.loop();
thread.start();
}
註:handler 處理訊息總是在建立該handler的線程中運行,而我們的訊息處理中,不乏更新UI的操作,不正確的線程直接更新UI將引發異常,因此我們需要即時注意handler所在的線程。
小結:
- handler 的處理運行是在建立該handler的線程中運行
- 一個looper對應一個messageQueue
- 一個線程對應一個looper
- 一個looper可以對應多個handler(這些handler在同一個線程中)
android handler、looper、message、messageQueue、