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取出消息处理