Android主线程向子线程发送消息

时间:2021-01-19 18:28:17

Android主线程向子线程发送消息

参考博客:http://www.cnblogs.com/xirihanlin/archive/2011/04/11/2012746.html

          http://blog.csdn.net/heng615975867/article/details/9194219

看了上一篇文章,你应该知道了Message、Looper、Messagequeue、Handler四个名字的含义。这里我先描述下线程中处理消息的过程。

Android主线程向子线程发送消息

在其他线程B中通过HandlerA通过SendMessage系列方法将消息发送到线程A的消息队列中,Looper将依次取出消息队列中的各个消息,并重新交给HandlerA对消息进行处理。

 

为了加深对它们的理解,下面我将以问答的形式进行进一步描述。

1、 子线程中如何创建、获取Looper对象?

我们知道,当我们创建一个线程时,这个线程并不包含Looper对象(当然,Android主线程会自动为自己创建一个Looper对象),子线程中我们可以使用Looper.prepare()方法来为该子线程创建一个Looper对象。当我们为线程创建Looper对象时,同时也会创建一个关联的MessageQueue对象。   当我们创建了Looper对象以后,那么我们通过Looper.myLooper()方法就可以获得当前线程的Looper对象。如果我们需要获取主线程的Looper对象,使用Looper.getMainLooper()方法即可。

2、Handler为什么能得到Looper从消息队列中取出的对象?

我们知道,当我们需要创建一个Handler时,我们只需要使用Handler  myHandler= newHandler();即可得到一个myHandler对象,但是实际上new Handler()等价于new Handler(Looper.myLooper()) ,即在创建Handler对象时,它就和Looper实现了关联,它自然就能从Looper那里取得消息任务。   这里需要注意的是,如果我们在子线程中直接newHandler()就会保运行时错误,因为子线程默认并不包含Looper对象,因此我们必须先调用Looper.prepare()方法位子线程创建一个Looper对象后,然后再通过new Handler()去创建Handler对象。

当然,对于同一个Looper对象,我们可以将它和多个Handler关联,那到时候发送的Message对象在取出的时候究竟交给哪一个Handler处理呢?实际上每一个Message都包含有一个target属性,它就记录着是哪一个Handler将它发送到消息队列的,因此在Looper将其取出的时候,会将其交给发送这个Message对象的Handler进行处理。


上一篇文章我们讲了如何在子线程中发送消息到主线程,这篇文章前面我们又理解了以上问题,那么新的问题来了,如何使子线程处理主线程的消息呢?

要实现线程对消息的处理,我们需要获得以下对象:与线程绑定的Looper对象、与Looper绑定的Handler对象,这样当Looper开始巡检的时候当发现消息就可以交给Handler去处理。具体代码如下:

 classLooperThread extends Thread {

                              public Handler myLooperHandler;

                              public void run() {

                                              Looper.prepare();

                                              mHandler = new Handler() {

                                                              public void handleMessage(Message msg) {

                                                                             // process incoming messages here

                                                              } };

                                              Looper.loop();

}}

注意到以上LooperThread类中出现了一个Looper.loop()方法,Looper.loop()方法就是Looper开始进行消息巡检的命令,它类似于一个无限循环,不断去查询消息队列中是否有消息等待取出,如果有,就直接交给myLooperHandler去处理,myLooperHandler处理完一个消息以后,Looper会继续巡检。因此,在Looper.loop()后面的代码是无法执行到的,这也就要求Handler的实例化必须在Looper.prepare();Looper.loop();之间完成。 

那么如果其他线程需要LooperThread处理一个消息的时候,只需要使用myLooperHandler通过sendMessage方法发送给LooperThread即可。当然,如果我们需要线程退出Looper巡检,只需要调用myLooperHandler.getLooper().quit()方法即可,此时Looper将不再继续巡检消息队列,Looper.loop()后面的代码也会得到执行。

了解了主线程向子线程发送消息,那么Android线程间消息的发送你是不是也就清楚了呢?