参考网页http://www.cnblogs.com/leon19870907/archive/2012/02/25/2367549.html
首先纠正之前的一个错误观点,Handler这个东西,我们一般用来干什么?
通常的答案是:UI线程负责更新视图,工作线程负责执行耗时操作,一般的组合是,开启工作线程进行耗时操作,操作结束之时,使用Handler向UI线程发送消息,让UI线程更新视图。
但这个只是片面的说法:更加完整的是,Handler是线程间通信的工具,不只是和UI线程进行通信。工作线程之间理论上也是可以进行相互通信的。
几个概念:
Lopper:每一个线程都会产生一个Lopper,这个相当于该线程的标志,用于管理线程的message,它会创建一个MessageQueue(消息队列)来存放Message(消息)。
Handler:与Lopper沟通的对象,可以push消息到MessageQueue,也可以从MessageQueue得到消息。
所以,最上面所说的(Handler的作用)就很好理解了:那就是,子线程通过Handler,将一个消息传递到了UI线程的消息队列,然后UI线程来执行消息队列的时候,就发现了这个消息,然后就更新了视图。
OK,继续:
说说Handler的构造函数:有参数的和没有参数的。
无参数的Handler(),那就是默认利用当前线程的Lopper来创建handler.
有参数的Handler(Lopper lopper) ,那就是使用参数中Lopper来创建Handler。
举例子:
Handler mHandler = new Handler(Lopper.getMyLopper());//使用当前线程中的Lopper来创建Handler
Handler mHandler = new Handler(Lopper.getMainLopper());//使用UI线程中的Lopper来创建Handler
另外,扩展一下:除了使用handler.sendMessage(message)让UI更新视图之外,还可以使用handler.post(runnable)的方式。
上图中,子线程new Thread调用mHandler来post一个runnable,runnable中改变UI视图。这种做法是可行的。
并且,handler的post方法,并不会创建一个新线程,而是使用UI线程来执行runnable的操作。
所以,以后不妨可以尝试这种写法来更新视图。
当有Runnable对象需要复用的时候,使用这个也许会让程序简洁一些。
对比handler.sendMessage():我们需要创建一个Message对象,然后使用创建handler时编写的handlerMessage条件分支去执行。
两种做法都可以,看情况使用,起码现在我写程序,多了一种选择。