Android消息机制之—Handler
1.2 Handler
/frameworks/base/core/java/android/os/Handler.java
Handler扮演者向MQ上添加消息和处理消息的角色,它通知MQ它要执行一个任务(sendMessage),并且loop到自己的时候执行该任务,整个过程是异步的。
*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. |
一个Handler允许发送与一个线程相关的Message和Runnable对象。每个Handler实例,都会和一个线程相连。如果创建一个新的Handler,它就会和线程的消息队列相连。
小结:一个线程可以有多个Handler,但只能有一个Looper。
public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + } } mLooper = Looper.myLooper(); //默认关联当前线程的Looper //looper不能为空,即默认的构造方法只能在looper线程中使用 throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } //直接把关联looper的MQ作为自己的MQ,因此它的消息将发送到关联//looper的MQ上。 }
|
以上就是讲Handler和Looper线程的绑定和联系,下面讲Handler的消息发送和消息处理。
Handler发送消息:
public final boolean post(Runnable r){ return sendMessageDelayed(getPostMessage(r), 0); } private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; } private static Message getPostMessage(Runnable r, Object token) { Message m = Message.obtain(); m.obj = token; m.callback = r; return m; } |
发送Runnable对象,它的run方法将在handler关联的looper线程中执行。在Handler中封装成Message。
post(Runnable),
postAtTime(Runnable, long),
postDelayed(Runnable, long),
sendEmptyMessage(int),
sendMessage(Message),
sendMessageAtTime(Message, long)
sendMessageDelayed(Message, long)
以上这些方法都是向MQ上发送消息的,字面上可见发送的消息为Runnable对象和Message对象。在源码中我们发现,Runnable对象也被封装为了Message对象。
下面分析一下,SendMessage函数,有利于理解Handler的处理过程:
从基本的sendMessage()开始,发现sendMessage调用了sendMessageDelayed()。
public final boolean sendMessage(Message msg){ return sendMessageDelayed(msg, 0); } public final boolean sendEmptyMessage(int what){ return sendEmptyMessageDelayed(what, 0); } |
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { Message msg = Message.obtain(); msg.what = what; return sendMessageDelayed(msg, delayMillis); }
|
发现sendEmptyMessageDelayed()最后也调用了sendMessageDelayed().
public final boolean sendMessageDelayed(Message msg, long delayMillis){ if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } |
sendMessageDelayed()调用了sendMessageAtTime();
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); } |
在sendMessageAtTime中,调用了enqueueMessage();
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; //message的target指向处理它的handler if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); } |
到这消息添加到了MQ中,并且每个消息的target都指向能够处理该消息的handler。
在loop()方法中的关键代码:
msg.target.dispatchMessage(msg); |
正常添加的消息为Message对象,而post发出的message,其callback为Runnable对象。
接下来Handler处理消息:
核心方法dispatchMessage();
public void dispatchMessage(Message msg) { if (msg.callback != null) { //如果消息设置了callback则为runnable消息,处理callback。 handleCallback(msg); } else { //如果handler本省设置了callback,执行callback if (mCallback != null) { // 这种方法允许让activity等来实现Handler.Callback接口,避免了//自己编写handler重写handleMessage方法 if (mCallback.handleMessage(msg)) { return; } } //没有callback,调用handler的钩子方法handleMessage handleMessage(msg); } } |
钩子函数由Handler的子类来实现。
/** * Subclasses must implement this to receive messages. */ public void handleMessage(Message msg) { } |
//处理runnable消息—直接运行run方法。
private static void handleCallback(Message message) { message.callback.run(); } |
对于开发者来说,只要实现handleMessage钩子函数和Runnable对象的run方法外,其他的都是透明的。
Handler的用处:
1. 可以在任意线程中发送消息,这些消息会发送到它关联的MQ上。
2. Handler是在它关联的looper线程中处理消息的。
通过Looper,Handler和Message的方式就解决了在非主线程中更新UI的问题。Android的主线程(UI线程)也是一个looper线程。