转自: http://blog.sina.com.cn/s/blog_8417aea80100v6a3.html
HandlerThread 类在官方文档中的描述如下:
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called. 翻译成中文大概是:
HandlerThread 这个类能方便的开启一个包含looper的线程,这个looper也能被用来创建一个handler对象(意思就是把looper以参数形式传递到handler的构造器),并提示我们注意:在用到 HandlerThread 时,同样必须调用start方法。
Android 提供了一个线程类 HanderThread 类,HanderThread类继承了Thread类,它封装了 Looper 对象,使我们不用关心 Looper 的开启和释放的细节问题(因为 Looper 的构造函数是私有的,对于其实例的获取比较麻烦,而 HandlerThread 帮我搞定了这些繁琐)。HandlerThread 对象中可以通过 getLooper 方法获取一个 Looper 对象引用。
其主要的方法有:
public Looper getLooper ()
Public Constructors
public Handler ()
public Handler (Handler.Callback callback)
public Handler (Looper looper)
接受消息发送和计划任务的处理是目标线程,它是通过Looper机制维护消息队列,如果应用中有包含更新UI处理,则要把更新UI的处理代码放置在目标线程中,这个时候还要保障更新UI的线程是主线程。
handler发送消息有两种方式,一种是post,另一种是send方式,send方式的话,那么通过handleMessage处理发送过来的消息;Handler对于Message的处理不是并发的。一个Looper 只有处理完一条Message才会读取下一条,所以消息的处理是阻塞形式的(handleMessage()方法里不应该有耗时操作,可以将耗时操作放在其他线程执行,操作完后发送Message(通过sendMessges方法),然后由handleMessage()更新UI)。
接下来我们再来说说Looper,它是用了收发消息并管理消息队列的,它的构造器是私有的,它的实例化需要通过 loop.prepare(),即初始化当前线程为looper,所以我们说,如果用的不是HandlerThread,而是一个普通的线程,那么如果此时又需要用到looper,那么必须在run方法的第一行写loop.prepare();为什么说looper是用来管理消息队列的,因为通过源码发现:
MessageQueue是在Looper的私有构造函数Looper()中实例化的;
总结一下,HandlerThread是被显式地通过new创建的实例,而与它绑定在一起的Looper是在HandlerThread的执行过程中被实例化的,相应的MessageQueue也是在这个过程中实例化的。
然后之前我也从不少地方,无论是视频还是论坛里得到的结论是:looper.loop实际上就是一个while(true)的死循环,MessageQueue是Looper保留的一份引用,通过它的next()[序列1]获取MessageQueue中的下一个要处理的消息,这个过程中如果没有相应的消息,执行它的线程会用this.wait()释放它所拥有的MessageQueue的对象锁而等待。