Looper有关键三个方法:构造方法,prepare(),loop().
Looper中维护一个MessageQueue。
MessageQueue是一个消息队列。用来管理消息。
Handle用于发出消息,以及处理message。
Looper的prepare的代码
- public static final void prepare() {
- if (sThreadLocal.get() != null) {
- throw new RuntimeException("Only one Looper may be created per thread");
- }
- sThreadLocal.set(new Looper(true));
- }
我们看一下Looper的构造方法:
- private Looper(boolean quitAllowed) {
- mQueue = new MessageQueue(quitAllowed);
- mRun = true;
- mThread = Thread.currentThread();
- }
我们来看看Looper.loop()方法。
- public static void loop() {
- final Looper me = myLooper();
- if (me == null) {
- throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
- }
- final MessageQueue queue = me.mQueue;
- // Make sure the identity of this thread is that of the local process,
- // and keep track of what that identity token actually is.
- Binder.clearCallingIdentity();
- final long ident = Binder.clearCallingIdentity();
- for (;;) {
- Message msg = queue.next(); // might block
- if (msg == null) {
- // No message indicates that the message queue is quitting.
- return;
- }
- // This must be in a local variable, in case a UI event sets the logger
- Printer logging = me.mLogging;
- if (logging != null) {
- logging.println(">>>>> Dispatching to " + msg.target + " " +
- msg.callback + ": " + msg.what);
- }
- msg.target.dispatchMessage(msg);
- if (logging != null) {
- logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
- }
- // Make sure that during the course of dispatching the
- // identity of the thread wasn't corrupted.
- final long newIdent = Binder.clearCallingIdentity();
- if (ident != newIdent) {
- Log.wtf(TAG, "Thread identity changed from 0x"
- + Long.toHexString(ident) + " to 0x"
- + Long.toHexString(newIdent) + " while dispatching to "
- + msg.target.getClass().getName() + " "
- + msg.callback + " what=" + msg.what);
- }
- msg.recycle();
- }
- }
上面的第二行final Looper me = myLooper();
具体代码是
public static Looper myLooper() {
return sThreadLocal.get();
}
public static Looper myLooper() {
return sThreadLocal.get();
}
也就是取出咱们放在sThreadLocal中的Looper.也就是说我们的prepare()方法必须先Loop()方法使用。这样才有looper对象。然后就是第6行,获取在Looper中的MessageQueue实例,然后第13行开始一个无限for循环,不断从MessageQueue里面获取Message,如果msg不存在的话,则return。如果msg存在的话,调用msg.target.dispatchMessgae()方法,去处理Message。
那msg的target是谁。不用想,肯定是Handler,但是Handler怎么就成了msg的target了呢,我们看一下Handler的代码。
- public Handler() {
- this(null, false);
- }
- 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;
- }
但是还是没有看到msg.target是在哪儿设置的。但是我们知道我们用Handler经常用的一个方法是sendMessage(Message msg)。
我们来看看相关的源码:
- public final boolean sendMessage(Message msg)
- {
- return sendMessageDelayed(msg, 0);
- }
- public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
- Message msg = Message.obtain();
- msg.what = what;
- return sendMessageDelayed(msg, delayMillis);
- }
- public final boolean sendMessageDelayed(Message msg, long delayMillis)
- {
- if (delayMillis < 0) {
- delayMillis = 0;
- }
- return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- }
- 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);
- }
原来sendMessage最后调用的是sendMessageAtTime方法,然后先获取到了咱们在构造函数中得到的MessageQueue。然后在调用enqueueMessage方法。
- private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
- msg.target = this;
- if (mAsynchronous) {
- msg.setAsynchronous(true);
- }
- return queue.enqueueMessage(msg, uptimeMillis);
- }
回过头,我们其实还在msg.target.dispatchMessage这个地方。
那dispatchMessage方法在干嘛呢??
- public void dispatchMessage(Message msg) {
- if (msg.callback != null) {
- handleCallback(msg);
- } else {
- if (mCallback != null) {
- if (mCallback.handleMessage(msg)) {
- return;
- }
- }
- handleMessage(msg);
- }
- }
- public void handleMessage(Message msg) {
- }
当然如果你Handler有了CallBack,且CallBack的handleMessage返回true的话,那么久不会在调用handler本身的handleMessage方法了。
总结一下:
Looper通过prepare方法生成一个在当前线程的Looper和这个Looper的MessageQueue。
Looper通过loop()方法无限循地从Message里面获取msg。然后交给msg的target去dispatchMessage。
Handler的构造方法把Handler与当前线程中的Looper以及它的MessageQueue关联起来。通过sendMessage等方法,把msg与Handler绑定起来,然后通过MessageQueue的enqueue方法把message加入到消息队列中。因为消息队列中的消息是不断取出的,然后就调用了Handler的dispatch方法去处理message。那最终可以是handleCallback(msg);这个方法去处理消息,或者Handler的CallBack去处理。或者通过Handler本身的handleMessage去处理消息。
学习的东西,写出来最重要了。