Handler消息机制

来源:互联网 发布:javascript重要吗 编辑:程序博客网 时间:2024/05/21 23:47

消息机制-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阶段的理解, 如大家有更深入的理解,可以告诉我,让我多涨涨知识面.

0 0
原创粉丝点击