线程/Handler/Looper/MessageQueue/Message之间的对应关系
- 一个线程对应一个Looper,一个Looper对应一个MessageQueue
- 一个线程可以对应多个handler,msg.target可以找到对应的handler。
主线程的Looper和loop()启动
- 主线程已经调用了Looper.prepareMainLooper(); Looper.loop();方法
- Looper.prepareMainLooper(); 创建了一个Looper对象,并与当前线程绑定
- (Looper的构造方法直接创建了一个消息队列),
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
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));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
子线程的Looper和loop()启动
如果直接在子线程new Handler(),会报**Can’t create handler inside thread that has not called Looper.prepare()**异常。因为子线程不会主动调用Looper.prepareMainLooper(); Looper.loop();方法
下面我们看一下Looper.prepare()方法。从prepare方法给当前线程初始化了一个looper对象让当前线程可以使用handler,但是需要手动调用loop()方法才能开启从消息队列轮询。
/** Initialize the current thread as a looper.
* This gives you a chance to create handlers that then reference
* this looper, before actually starting the loop. Be sure to call
* {@link #loop()} after calling this method, and end it by calling
* {@link #quit()}.
*/
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关联起来
sThreadLocal.set(new Looper(quitAllowed));
}
- 子线程创建handler的前提是:子线程必须有looper。
class MyThread extends Thread {
public void run() {
// 其它线程中新建一个handler
Looper.prepare();// 创建该线程的Looper对象,用于接收消息,在非主线程中是没有looper的所以在创建handler前一定要使用prepare()创建一个Looper
myThreadHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
}
};
Looper.myLooper().loop();//建立一个消息循环,该线程不会退出
}
}
- 子线程可以获取主线程的handler
new Thread(new Runnable() {
@Override
public void run() {
Handler handler = new Handler(Looper.getMainLooper());//得到UI线程中的handler对象
handler.post(new Runnable() {
@Override
public void run() {
//这儿写逻辑代码
}
});
}
}).start();
创建Handler
Handler类
//Handler构造方法
public Handler(Callback callback) {
this(callback, false);
}
public Handler(Callback callback, boolean async) {
// 子线程如果不调用Looper.prepare()的话,mLooper=null
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
//Handler构造方法的回调
public interface Callback {
boolean handleMessage(Message var1);
}
//message分发方法
public void dispatchMessage(Message msg) {
//如果message设置了callback,直接执行message的callback
if (msg.callback != null) {
handleCallback(msg);
} else {
//如果message没有设置callback,那么交给handleMessage方法
//也就是new Handler()时重写的方法
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
将Message加入到MessageQueue
handler发送消息,将Message加入到MessageQueue 代码如下:
//如果是发送emptyMessage,会默认Message.obtain()获取一个message设置进去
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) {
// 发送消息时,会通过msg.target设置handler
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
Looper.loop()从MessageQueue中取出Message
Looper类
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;
// 略......
// 开启无限循环
for (;;) {
// 通过queue.next()获取Message
Message msg = queue.next(); // might block
// 略......
try {
// 调用当前message绑定的handler的dispatchMessage方法
msg.target.dispatchMessage(msg);
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
// 略......
msg.recycleUnchecked();
}
}
总结:
1.主线程自带一个Looper和MessageQueue,自启动轮询
2.子线程需要调用Looper.prepare()创建一个Looper,创建Looper的同时,也给当前Looper创建了一个MessageQueue。创建完成之后需要手动调用Looper.myLooper.loop()开启轮询
3.通过构造方法创建Handler的时候,给当前handler绑定了Looper和MessageQueue,handler发送信息时将Message加入对应的MessageQueue
4.loop()方法不停的轮询MessageQueue,取出Message,通过msg.target.dispatchMessage(msg);回调创建Handler时重写的Callback方法,将msg交给对应的handler