关于 Handler
的用法相信大家都应该知道,比如这样:
|
|
我们从 Handler
的构造方法开始看起:
|
|
先调用了 Looper.myLooper()
赋给 mLooper
,点进去看看 myLooper()
方法的实现:
|
|
很简单,返回一个与当前线程相关联的 Looper
对象。如果调用线程没有与 Looper
关联则返回 null
。那怎么关联呢?往下看。
获取到 Looper
之后调用 mLooper.mQueue
获取到当前线程关联的 Looper
中的消息队列 mQueue
。
Looper
中的消息队列 mQueue
是在 Looper
的构造方法中创建的:
|
|
而 Looper
的构造方法是在哪儿调用的呢?看 prepare()
方法:
|
|
当 prepare()
方法被调用的时候,就会初始化一个 Looper
对象并与当前线程关联起来,而 Looper
中维护着一个消息队列 MessageQueue
。
当我们 new
一个 Handler
之后,调用 sendMessage(message)
方法或者是 sendXXX
等等诸如此类的方法发送消息,
最后都会走到 sendMessageAtTime
这个方法中,点进去看看它的实现:
|
|
如果 queue
不为 null
,调用 enqueueMessage
方法,再点进去看看实现:
|
|
在这里把 this
赋给了 msg.target
,这里的this
就是当前的 handler
对象,Message
中的 target
就是 Handler
,在这里就把 Handler
和 Message
关联起来了,然后调用 MessageQueue
中的 enqueueMessage
方法,把当前的消息传到消息队列中去:
|
|
消息已经发出去了,那么在哪儿接收呢?
调用 Looper.loop()
来循环消息队列:
|
|
看36行,调用了 msg.target.dispatchMessage(msg)
,msg.target
就是 Handler
,就是调用了 Handler
的 dispatchMessage
方法来分发消息的:
|
|
msg.callback
是什么?是一个 Runnable
,如果指定了 Message
的 callback
,那就走 handleCallback(msg)
:
|
|
否则,如果 mCallback != null
,则执行 mCallback.handleMessage(msg)
:
|
|
如果 mCallback.handleMessage(msg)
返回 true
,则执行完毕,否则,再执行最后的 handleMessage(msg)
:
|
|
这个 handleMessage
就是我们创建 Handler
的时候重写的那个 handleMessage
,重写这个方法来处理接受到消息后的逻辑:
|
|
到此,整个流程就走完了,整理一下:
Looper.prepare()
:调用Looper.prepare()
的时候创建一个包含MessageQueue
的Looper
对象与当前线程关联;new Handler()
:在构造方法中通过Looper.myLooper()
获取当前线程的Looper
对象,然后获取了 Looper 中的 MessageQueue;- 调用
sendXXX()
: 会调用enqueueMessage()
,把当前Handler
实例赋给Message
的target
,最终调用MessageQueue
的enqueueMessage()
,把这个 Message 放进消息队列中; - 调用
Looper.loop()
循环消息队列,msg.target.dispatchMessage(msg)
分发消息; - 消息处理。
有人有疑问我们并没有调用 Looper.prepare()
和 Looper.loop()
,那是因为在 ActivityThread
的 main
方法中已经为我们写好了:
|
|
在21行调用了 Looper.prepareMainLooper()
:
|
|
创建了唯一的 sMainLooper
实例,然后在37行调用了 Looper.loop()
。(PS:所以在主线程调用 Looper.myLooper()
和 Looper.getMainLooper()
是一样的)
关于 Handler
的 post()
:
|
|
|
|
通过 getPostMessage
创建一个 Message
,并把 runnable
传给了 Message
的 callback
:
|
|
然后调用 sendMessageXXX -> sendMessageAtTime -> enqueueMessage -> MessageQueue enqueueMessage …… 后面流程都一样了,然后在 dispatchMessage
的时候,因为 msg.callback != null
,所以就执行了 handleCallback(msg)
:
|
|
就是执行了 Runnable
的 run()
。
完毕。