Android源码阅读之Looper

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

            }

        }

.........

        msg.recycleUnchecked();

    }

}

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

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

总结

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

开启loop从MessageQueer取出消息处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值