Handler源码
在Andorid-27中查看源码
Handler的构造函数:
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; } public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }
上面的两个构造函数中可以看到唯一的区别是一个有默认的Looper,一个需要我们传入Looper且不能为null。默认的Looper通过Looper.myLooper()获取,关于Looper参考Looper源码
在使用Handler时的常用方法:sendMessage()、sendMessageDelayed()、sendEmptyMessage()、sendEmptyMessageDelayed()。我们在源码中分别查看这几个方法,可以发现最终调用的都是sendMessageAtTime方法。在sendMessageAtTime方法中发现最终调用的是MessageQueue的enqueueMessage方法,下面我们来看该方法的源码:
boolean enqueueMessage(Message msg, long when) { if (msg.target == null) { throw new IllegalArgumentException("Message must have a target."); } if (msg.isInUse()) { throw new IllegalStateException(msg + " This message is already in use."); } synchronized (this) { if (mQuitting) { IllegalStateException e = new IllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w(TAG, e.getMessage(), e); msg.recycle(); return false; } msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; for (;;) { prev = p; p = p.next; if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; // invariant: p == prev.next prev.next = msg; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; }
在该方法中可以看到,如果当前消息队列中没有消息(mMessages==null),则把当前消息加入到消息队列中(mMessages=msg);否则遍历消息队列,当该消息的when<消息队列中的消息的when时将该消息插入到消息队列中,否则将其插入到消息队列末尾。
从中我们可以发现消息队列的实现是利用Message中的next形成的链式结构,然后根据Message中的when在加入消息时去调整链式结构中消息的顺序,同时保存了链式结构中的头部消息。我们在发送消息的时候同时也注明了我们什么时候要使用消息,要么立即使用,要么多久后使用。消息队列就根据我们要使用消息的时间将消息存储在一个链式结构中,在使用时每次都取出消息队列中的第一个消息去处理。
在Looper的loop方法中我们看到从消息队列中取出消息交给dispatchMessage方法去处理。
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
在dispatchMessage中看到消息最后通过下面任意途径被处理了:
- 消息自身的callback里面的run方法。
- handler的callback的handleMessage方法。
- handler自身的handleMessage方法。
我们一般使用最多的就是在创建Handler的时候重写handleMessage方法,有利于对消息的统一处理,同样也减少了Callback的创建。