Handler、Looper、MessageQueue源码解析

首先打开Looper类,可以看到头部的说明中有一个小例子,如下:

class LooperThread extends Thread {
    public Handler mHandler;

    public void run() {
        Looper.prepare();

        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here
            }
        };

        Looper.loop();
      }
}

这是一个在子线程中创建Handler的例子,我们就以这个例子来讲解。

Looper.prepare();

在子线程中,在创建Handler之前先执行了Looper.prepare(),我们先来看下Looper.prepare()的代码:

static final ThreadLocal sThreadLocal = new ThreadLocal();

public static void prepare() {
    prepare(true);
}

private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    //创建Looper对象,并把Looper存入ThreadLocalMap
    sThreadLocal.set(new Looper(quitAllowed));
}

//ThreadLocal的set()方法
public void set(T value) {
    //获取当前线程
    Thread t = Thread.currentThread();
    //获取当前线程的ThreadLocalMap
    ThreadLocalMap map = getMap(t);
    //把ThreadLocal为key,Looper为value存入ThreadLocalMap
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}

//Looper的构造方法,创建了一个MessageQueue
private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}

Looper.prepare()的作用就是创建一个Looper和一个MessageQueue对象,Looper.prepare()只能调用一次,再次调用就会抛throw new RuntimeException("Only one Looper may be created per thread")异常,所以每一个线程对应唯一的一个Looper和一个MessageQueue。

new Handler()

public Handler() {
    this(null, false);
}

public Handler(Callback callback, boolean async) {
    if (FIND_POTENTIAL_LEAKS) {
        final Class 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());
        }
    }

    //获取当前线程的Looper对象(Looper.myLooper()的源码在下面)
    mLooper = Looper.myLooper();
    if (mLooper == null) {
        throw new RuntimeException(
            "Can't create handler inside thread that has not called Looper.prepare()");
    }
    //获取当前线程的Looper对应的MessageQueue
    mQueue = mLooper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

从上面可以看出Handler的构造方法,其实就是获取当前线程的Looper和MessageQueue,我们通过Handler的sendMessage发送Message,都是把Message放到MessageQueue中。

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);
}

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    //把当前Handler对象赋值给msg.target
    msg.target = this;
    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    //把Message放到MessageQueue中
    return queue.enqueueMessage(msg, uptimeMillis);
}

Looper.myLooper()

Looper.myLooper()先获取当前线程,再获取当前线程的ThreadLocalMap,然后从ThreadLocalMap中获取先前存入的Looper。

public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}
//ThreadLocal的get()方法
public T get() {
    //获取当前线程
    Thread t = Thread.currentThread();
    //获取当前线程的ThreadLocalMap
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        //以ThreadLocal为key从ThreadLocalMap取出保存的Looper
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null)
            return (T)e.value;
    }
    return setInitialValue();
}

Looper.loop()

循环从MessageQueue中取出Message,通过msg.target就是发送Message的Handler,调用Handler的dispatchMessage(msg)分发消息。

public static void loop() {
    //获取当前线程的Looper对象
    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();

    //循环从MessageQueue中取出Message
    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
        final Printer logging = me.mLogging;
        if (logging != null) {
            logging.println(">>>>> Dispatching to " + msg.target + " " +
                    msg.callback + ": " + msg.what);
        }

        final long traceTag = me.mTraceTag;
        if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
            Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
        }
        try {
            //msg.target就是发送Message的Handler,dispatchMessage(msg)分发消息
            msg.target.dispatchMessage(msg);
        } finally {
            if (traceTag != 0) {
                Trace.traceEnd(traceTag);
            }
        }

        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.recycleUnchecked();
    }
}

msg.target.dispatchMessage(msg)

Handler的dispatchMessage(msg)把Message交给对应的方法处理,这里是handleMessage(msg)。

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) {
}

总结

Looper的prepare()方法创建了一个Looper对象,并且保证每个线程最多只有一个Looper对象。在主线程中,系统已经初始化了一个Looper对象,因此可以直接创建Handler,在子线程必须调用Looper.prepare()创建一个Looper对象,并调用Looper.loop()启动它。

Handler的构造方法,会获取当前线程的的Looper,进而获得关联的MessageQueue,Handler的sendMessage会给msg.target赋值为自身,然后把Message存入MessageQueue。

Looper不断的从MessageQueue中取出Message,通过msg.target获取对应的Handler,调用Handler的dispatchMessage(msg)把Message交给对应的方法处理。

你可能感兴趣的:(Handler、Looper、MessageQueue源码解析)