消息机制-Handler
一、创建Handler对象
上面的图说明,在new Handler()时,会通过无参数构造调用有两个参数的的构造
Handler(Callback callback,
boolean
async),就可以获取(关联)当前线程的looper和messageQueue了。
二、发送消息sendMessage
在主线程创建handler实例对象,在子线程使用handler的sendMessage方法把message发出去,sendMessage中调用
enqueueMessage(queue, msg, uptimeMillis)把消息message放到消息队列中
三、处理消息handleMessage
Handler在
dispatchMessage(Message msg) 中调用handleMessage(
Message msg
)方法,而handleMessage()方法中的具体内容要子类实现,因此想知道Handler对象是如何拿到message对象并传给handleMessage()方法,就需要知道在哪里使用了
dispatchMessage(Message msg)
?
查看源码会发现在Looper类中loop方法中:
loop()方法一执行就会进入死循环,并通过MessageQueue队列的next()方法获取消息message对象,获得msg后会找到绑定的handler对象(即在sendMessage时的target),然后调用handler对象的dispatchMessage(Message msg)方法把msg传递出去,而dispatchMessage方法中调用的就是我们自己实现的handlMessage(Message msg),这时msg对象就到了主线程中供我们使用了
官方文档对handler的解释
/**
* A Handler allows you to send and process {@link Message} and Runnable
* objects associated with a thread's {@link MessageQueue}. Each Handler
* instance is associated with a single thread and that thread's message
* queue. When you create a new Handler, it is bound to the thread /
* message queue of the thread that is creating it -- from that point on,
* it will deliver messages and runnables to that message queue and execute
* them as they come out of the message queue.
*
* <p>There are two main uses for a Handler: (1) to schedule messages and
* runnables to be executed as some point in the future; and (2) to enqueue
* an action to be performed on a different thread than your own.
*
* <p>Scheduling messages is accomplished with the
* {@link #post}, {@link #postAtTime(Runnable, long)},
* {@link #postDelayed}, {@link #sendEmptyMessage},
* {@link #sendMessage}, {@link #sendMessageAtTime}, and
* {@link #sendMessageDelayed} methods. The <em>post</em> versions allow
* you to enqueue Runnable objects to be called by the message queue when
* they are received; the <em>sendMessage</em> versions allow you to enqueue
* a {@link Message} object containing a bundle of data that will be
* processed by the Handler's {@link #handleMessage} method (requiring that
* you implement a subclass of Handler).
*
* <p>When posting or sending to a Handler, you can either
* allow the item to be processed as soon as the message queue is ready
* to do so, or specify a delay before it gets processed or absolute time for
* it to be processed. The latter two allow you to implement timeouts,
* ticks, and other timing-based behavior.
*
* <p>When a
* process is created for your application, its main thread is dedicated to
* running a message queue that takes care of managing the top-level
* application objects (activities, broadcast receivers, etc) and any windows
* they create. You can create your own threads, and communicate back with
* the main application thread through a Handler. This is done by calling
* the same <em>post</em> or <em>sendMessage</em> methods as before, but from
* your new thread. The given Runnable or Message will then be scheduled
* in the Handler's message queue and processed when appropriate.
*/
Looper
Looper中有两个最主要的方法prepare()和loop()。
从图中可以看出,当调用prepare()方法时,会创建一个新的Looper对象,并新建一个MessageQueue. 而且会把Looper对象存进ThreadLocal中。
如果我们在MainActivity中调用Looper.prepare()会怎样呢?
结果就是会报出一个runtimeException:only one Looper may be created per thread. 也就是说当我们的MainActivity(或者说UI线程更确切)创建时已经给我们创建了一个Looper对象。那UI线程是如何创建Looper的呢?其实是android环境系统给我们调用了prepareMainLooper()。我们只需要在主线程new handler()就可以获取到这个looper对象啦。下面是looper的一段源码。
而loop方法就是上面介绍handler的handleMessage方法时说的,在死循环中一直去获取messageQueue队列中的消息,直到没有消息才结束进入阻塞状态,有消息的时候系统会再次开启loop
MessageQueue
在MessageQueue中也是有两个最重要的方法:enqueueMessage()(存信息)和next()(取信息),这里就不附源码了。查看源码会发现这两个方法并不是一直处于活动状态,有可能会阻塞,有新的message时才会唤醒。
以上纯属个人在初学Android阶段的理解, 如大家有更深入的理解,可以告诉我,让我多涨涨知识面.