Handler的工作原理
多线程里经常用到Handler和Message,但原理一直不知道,今天花了一天研究了下,看博客+Android源码,算是大概弄明白了,大概工作流程如下。
1.初始化looper
UI线程生成的时候会自动调用Looper.prepareMainLooper()
和Looper.loop()
,初始化threadLocal
的looper
,初始化looper
的MessageQueue
,并让这个looper
开始循环,从它的MessageQueue
中不断获取Message
。其他线程不会自动调用prepare和loop,用到的话需要手动调用。
2.初始化Handler
Handler
的构造函数会获得当前线程的looper
以及该looper
的messageQueue
。如果这里looper
为空,也就是当前线程没有调用过Looper.prepare()
,就会抛出RuntimeError
。
3.发送消息
Handler
的sendMessage(Message msg)
方法会将msg
的target
设为this
,也就是当前这个Handler
,然后调用messageQueue
的enqueueMessage(msg)
方法将Message
加入消息队列。
4.接收消息
第1步中提到的looper.loop()
进行无条件循环,在循环里调用MessageQueue.next()
方法获取消息,MessageQueue.next()
本身也包含一个无条件循环。如果没有待处理的消息,只有当ptr=0
或mQuite=true
的时候才会返回null
,其他时候都是continue
的;如果有待处理的消息就返回这个Message
,looper
会调用Message.target.dispatch()
让handler处理消息,这里面就会调用到我们自己构造Handler
类时@Override
的handleMessage()
方法了,处理完后继续之前的无条件循环获取消息。
5.looper阻塞UI线程的疑问
问题:既然
looper
是个无条件的死循环,为什么它没有阻塞线程呢?
答案是:一句话解释,UI线程消息循环开始后,所有的操作都是在这个loop()
里完成的。
完整的回答如下,摘自stackoverflow:
At some point (probably before any activities and the like are created) the framework has set up a Looper
(containing a MessageQueue
) and started it. From this point on, everything that happens on the UI thread is through that loop. This includes activity lifecycle management and so on. All callbacks you override (onCreate()
, onDestroy()
…) are at least indirecty dispatched from that loop. You can see that for example in the stack trace of an exception. (You can try it, just write int a = 1 / 0
; somewhere in onCreate()
…)
see:
http://410063005.iteye.com/blog/1750632
http://stackoverflow.com/questions/5193913/handlers-messagequeue-looper-do-they-all-run-on-the-ui-thread