Android Handler的handleMessage()、sendMessage()、dispatchMessage()的区别
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(),但是另外两个先出结果了。