sendMessage()
定義好handler后,在其他線程訪問這個線程的handler,調用sendMessage()發送信息給主線程的handler。內部是通過消息隊列的方式依次傳遞。
handleMessage()
在定義自己的Handler的時候都會重寫Handler的handleMessage()方法來對拿到的消息進行處理,因此這個方法應該是運行在接收消息的線程的。(例如下載內容->更新UI,handleMessage()運行在主線程)。
很無奈的是這個方法在父類Handler中就是一個public的方法,因此如果不小心在該寫sendMessage()的地方寫了handleMessage(),就會造成handleMessage()中寫的內容運行在子線程中,然后使用了導致修改UI失敗等錯誤。
(類似於新建了一個線程,然后調用run方法去執行它的Runnable了,而沒有執行start開辟新線程)
dispatchMessage()
dispatchMessage的調用和handleMessage情況類似,內部實際上還是調用handleMessage(),因此,直接調用也是無法回到主線程的。
代碼示例
Thread t1= new Thread(new Runnable() {
@Override
public void run() {
handler.handleMessage(Message.obtain());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendMessage(Message.obtain());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.dispatchMessage(Message.obtain());
}
});
t1.setName("子線程");
t1.start();
@Override
public void handleMessage(@NonNull Message msg) {
Log.d(TAG, "handleMessage: handler里的線程:"+Thread.currentThread().toString());
}
運行可以看到結果如下:
handleMessage: handler里的線程:Thread[子線程,5,main]
handleMessage: handler里的線程:Thread[main,5,main]
handleMessage: handler里的線程:Thread[子線程,5,main]
證明只有sendMessage()才可以讓消息正確傳達到主線程。
【為啥要在發消息之間暫停一秒呢?】
因為handleMessage和dispatchMessage不牽涉到線程間的通信,速度要比sendMessage快,如果不加,那么運行結果就有可能變成——我先調用了sendMessage(),但是另外兩個先出結果了。