1.Handler的使用
- 如图所示,需要做的操作有两步: public class MainActivity extends AppCompatActivity {- @Override - protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); final Handler handler=new Handler(){ @Override - public void handleMessage(Message m){ //更新ui操作 - } - }; new Thread(){//子线程开启 - @Override - public void run(){ Message m=new Message(); - handler.sendMessage(m); - } - }; - } - } 
- 在主线程中实例化一个Handler,并且重写HandleMessage方法用来处理子线程发送来的消息。 
- 在子线程中,首先声明Message对象,并将Message使用主线程中实例化的Handler的sendMessage(Message)方法发送给主线程。 
2.Handler的机制
- 在使用sendMessage和handleMessage之前是有很多已经隐藏的封装好的过程的,现在一一讲解。 
2.1 被消息传递的线程A准备
- 首先要在被消息传递的线程中创建Looper,因为Handler创建的时候要绑定当前线程的Looper,使用Looper.prepare()建立。 
- Looper.prepare() public static void prepare() {- prepare(true); - }private static void prepare(boolean quitAllowed) {if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); - } - sThreadLocal.set(new Looper(quitAllowed)); - }private Looper(boolean quitAllowed) { - mQueue = new MessageQueue(quitAllowed); - mThread = Thread.currentThread(); - } - 总的来说,prepare干了两件事:创建MessageQueue和绑定当前线程。 
- 然后使用Looper.loop()让Looper开始循环访问MessageQueue。 
- Looper.loop(); public static void loop() { // 拿到与当前线程关联的looper对象- final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); - } final MessageQueue queue = me.mQueue; - ....................................... for (;;) { - Message msg = queue.next(); // might block - ................................... - msg.target.dispatchMessage(msg); - .......................................... - msg.recycleUnchecked();// 回收Message对象 - } - } - 总的来说,loop干了三件事: - 1.拿到当前线程的looper。 - 2.根据looper拿到MessageQueue。 - 3.使用for循环对MessageQueu进行无限循环询问。 - 在for循环中也主要干了三件事: - 1.从消息队列中取消息,如果没有就阻塞。 - 2.调用 
 msg.target.dispatchMessage(msg)方法对Message进行处理。- 3.处理完成后调用msg.recycleUnchecked()回收资源。 
- 创建Handler,作为线程间通信的工具。 public Handler(Looper looper, Callback callback, boolean async){- mLooper = looper; - // 与这个Handler关联的Looper中的消息队列 - mQueue = looper.mQueue; - ............... - } - 创建Handler时将当前线程的Looper和Looper中的MessageQueue取到。 
2.2 传递消息的线程B准备
- 创建Message时,使用Message.obtain()的效果大于New Message(),因为享元模式,维护了一个大小为50的Message对象池,比重复去创建Message更加高效。 
- Handler.sendMessage(Message)方法最终会调用sendMessageAtTime方法。 public boolean sendMessageAtTime(Message Message, long uptimeMillis) { // 1. 获取Hndler中的消息队列- MessageQueue queue = mQueue; if (queue == null) { - RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); - Log.w("Looper", e.getMessage(), e); return false; - } // 2. 将要发送消息和时间入队 - return enqueueMessage(queue, Message, uptimeMillis); - } - 总的来说,做了两件事: - 1.获取handler中的MessageQueue。 - 2.调用enqueueMessage方法。 - enqueueMessage()方法代码如下: private boolean enqueueMessage(MessageQueue queue, Message Message, long uptimeMillis) { // 1. 将Handler赋值给Message的target- Message.target = this; if (mAsynchronous) { - Message.setAsynchronous(true); - } // 2. 将Message加入到消息队列中(还有Handler) - return queue.enqueueMessage(Message, uptimeMillis); - } - 总的来说,做了两件事: - 1.将handler赋值给Message.target。 - 2.并且将Message放入MessageQueue中。 
2.3 线程间通信
- 线程B的sendMessage流程执行完毕,至于线程A的Looper和Handler都已经创建好了,并且开始处理MessageQueue中的Message,还记得之前for循环中 public void dispatchMessage(Message msg) {
 Message.target.dispatchMessage()方法吗,其实这里的Message.target就是handler,而且dispatchMessage()方法的源码如下:- .......... - handleMessage(msg); - } - 在其中调用了handleMessage()方法,并且handleMessage()方法是个空方法,没有内容。所以我们只用重写这个方法就可以对线程B返回的消息进行处理了。 
3.一些问题
- 为什么Activity主线程没有执行Looper.prepare()和Looper.loop()? - 因为在ActivityThread的main方法中已经执行了这两个方法。 
- 一个线程可以拥有几个Looper?几个Handler? - 一个线程只能拥有一个Looper,无数个Handler。 
- 如何从主线程发送消息给子线程? - 在子线程中先建立Looper,然后再建立Handler,依靠sendMessage和handleMessage即可。 
文/breakingsword(简书作者)
原文链接:
http://www.jianshu.com/p/8862ab82d0f4

