Looper在消息机制中的作用是从MessageQueue中取消息以及让Handler去处理这个消息

在Looper类上面有一段说明,意思是消息机制在线程中的使用示例

* <pre>
*  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();
*      }
*  }</pre>

从上我们可以看到消息机制的创建

先是执行Looper.prepare---新建一个Looper并保存在ThreadLocal中

然后创建Handler---通过Looper.myLooper方法得到当前线程的Looper,并再一步得到messagequeue

最后执行Looper.loop方法开启循环读取消息,消息机制开始生效


Looper.prepare

我们可以看到在Looper类中定义了以下变量

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();//作用保存Looper到当前线程
private static Looper sMainLooper;  // 主线程Looper
final MessageQueue mQueue;//消息队列


接下来看下prepare方法

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

    sThreadLocal.set(new Looper(quitAllowed));
}

可以看到prepare最终调用的是prepare(boolean quitAllowed)方法

quitAllowed意思是 是否允许终止Messagequeue的循环

从prepare(boolean quitAllowed)我们可以看到一个线程最多只能拥有一个Looper对象,

为空则创建一个Looper对象并且保存到sThreadLocal中去


Looper构造函数

private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}

在构造函数中 创建了一个Messagequeue对象,并且得到了当前线程

这时候Looper与messagequeue已经完成了绑定

new MessageQueue(quitAllowed)中的quitAllowed表示当前的消息链表查询能否允许被停止

prepare方法的作用是创建一个Looper保存在当前线程ThreadLocal中,并且完成Looper与MessageQueue的绑定

prepare在一般子线程开启消息机制中才会被调用


在Android主线程开启消息机制中调用的是prepareMainLooper()

public static void prepareMainLooper() {
    prepare(false);
    synchronized (Looper.class) {
        if (sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");

        sMainLooper = myLooper();

}

可以看到主线程调用的prepare(boolean quitAllowed)中的quitAllowed值为false,这意味着主线程的Messagequeue不能被停止,也就是主线程的消息机制不会被停止


如何获得当前线程保存的Looper对象

public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}


如何获得主线程保存的Looper对象

public static Looper getMainLooper() {
    synchronized (Looper.class) {
        return sMainLooper;

}

Looper.loop

执行了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.");

    ........
    for (;;) {
        Message msg = queue.next(); // might block
        if (msg == null) {
            // No message indicates that the message queue is quitting.
            return;

........
            msg.target.dispatchMessage(msg);
        } finally {
            if (traceTag != 0) {
                Trace.traceEnd(traceTag);


.........


}

从loop方法可以看出里面是在不断循环的从Messagequeue队列中取出消息,只有当queue.next返回null时,循环停止,退出loop方法,消息机制失效

如果queue.next不返回null的话 则调用被取出的msg.target.dispatchMessage 回到msg.target指向的handler中处理

总结

Looper主要是完成了在当前线程中创建对象并且保存在ThreadLocal中,完成Looper与MessageQueue的绑定关联,

开启loop从MessageQueer取出消息处理