handler 通過sentMessage 發送到 MessageQueue中,通過Looper的處理(可以通過Looper.myQueue()得到當前線程的消息隊列)
一個for 循環 ,循環從MessageQueue中拿消息進行處理
public static void loop() { final Looper me = myLooper(); //獲得當前的Looper if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; //獲取當前Looper的消息隊列 //...... for (;;) { Message msg = queue.next(); //取出隊頭的消息 if (msg == null) { // 如果消息為空,則跳過,繼續執行下一個message return; } //...... try { msg.target.dispatchMessage(msg); //...... } finally { //...... } //...... msg.recycleUnchecked(); //回收可能正在使用的消息 } }
然后通過dispatchMessage 分發到相對應的target (即發送消息的那個Handler)
handler 進行handlerMessage的回掉
APP應用啟動的時候在主線程會創建一個MainLooper
所以在主線程創建的handler 是可以更新UI的 因為默認的looper在主線程,
而子線程是直接創建handler會報錯,必須在創建handler之前給該子線程創建一個looper (Lopper.prepare)
new Thread(new Runnable() { public void run() { Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { Toast.makeText(getApplicationContext(), "handler msg", Toast.LENGTH_LONG).show(); } }; handler.sendEmptyMessage(1); }; }).start();
上面找個會報錯
new Thread(new Runnable() { public void run() { Looper.prepare(); // 此處獲取到當前線程的Looper,並且prepare() Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { Toast.makeText(getApplicationContext(), "handler msg", Toast.LENGTH_LONG).show(); } }; handler.sendEmptyMessage(1); Looper.loop();//不斷遍歷 消息隊列中的消息 }; }).start();
一個線程有且只能綁定一個Looper,只有一個messageQueue ,可以創建無數個handler
handlerMessage 所在的線程是該looper所在的線程,即創建該Looper的線程。