文章出处:http://blog.csdn.net/shift_wwx
之前 Android异步消息处理线程之----Looper+MessageQueue+Handler 一文中将了一下Android 中异步消息处理的流程。
网上对于Handler 的讲解很详细了,这里根据 Source code 说一下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.
Handler 是用来发送和处理与一个线程的MessageQueue 有关联的Message 和 Runnable。
一个Handler 与一个线程以及此线程的MessageQueue有关联。
新建一个Handler 的时候,要与一个已经创建好的线程的MessageQueue 绑定。这样Handler 就可以发送message 和runnable 到消息队列,并且处理从消息队列发出来的回调。
构造函数就不一一附上,其中有参数的,没参数的。没参数的构造是指callback 为null。有参数的构造有传callback,looper或是looper + callback等。
主要来看一下:
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: " + klass.getCanonicalName()); } } mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }这里可以看到 Android异步消息处理线程之----Looper+MessageQueue+Handler 中说到的,handler对象只能添加到有消息队列的线程中。
通过构造函数可以看到,handler 是创建的时候可以不传Looper,那也就是说这个时候的handler 是在主线程中,也就是UI线程。在应用中可能一些费时、阻塞的东西可以通过消息队列来处理,这个时候可以新建一个Thread,将Thread 中处理消息队列,最后通过handleMessage 在主线程中处理UI 的操作。
那么关键就是消息队列的形成:
通过 Handler sendMessage 与 obtainMessage (sendToTarget)比较 看到,我们还是尽量用obtainMessage 来获取msg obj
public final Message obtainMessage(int what) { return Message.obtain(this, what); }
public void sendToTarget() { target.sendMessage(this); }至于new Message 与obtainMessage 有什么区别,可以看一下 Handler sendMessage 与 obtainMessage (sendToTarget)比较
最终会调用到:
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); }最终会往handler 所在的Lopper 里面的MessageQueue 存msg。
msg.target.dispatchMessage(msg);
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }这个逻辑也是需要注意的:
1)当handler 有Runnable 处理的时候,会去处理Runnable
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); } public final boolean postAtTime(Runnable r, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r), uptimeMillis); } public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r, token), uptimeMillis); } public final boolean postDelayed(Runnable r, long delayMillis) { return sendMessageDelayed(getPostMessage(r), delayMillis); } public final boolean postAtFrontOfQueue(Runnable r) { return sendMessageAtFrontOfQueue(getPostMessage(r)); }2)如果没有Runnable 有Callback 的时候,处理Callback
public interface Callback { public boolean handleMessage(Message msg); }3)如果上面都没有,如果需要处理msg,就需要override handler的函数
public void handleMessage(Message msg) { }
public final void removeCallbacks(Runnable r) { mQueue.removeMessages(this, r, null); } public final void removeCallbacks(Runnable r, Object token) { mQueue.removeMessages(this, r, token); }
public final void removeMessages(int what) { mQueue.removeMessages(this, what, null); } public final void removeMessages(int what, Object object) { mQueue.removeMessages(this, what, object); }