Message Queue按照先进先出执行。 每个message queue都会有一个对应的Handler。Handler会向message queue通过两种方法发送消息:sendMessage或post。这两种消息都会插在message queue队尾并按先进先出执行。但通过这两种方法发送的消息执行的方式略有不同:通过sendMessage发送的是一个message对象,会被Handler的handleMessage()函数处理;而通过post方法发送的是一个runnable对象,则会自己执行。
对于子线程使用Looper,API Doc提供了正确的使用方法:
package com.test; import android.os.Handler; import android.os.Looper; import android.os.Message; class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); //创建本线程的Looper并创建一个MessageQueue mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); //开始运行Looper,监听Message Queue } }这个Message机制的大概流程:
通过分析Activity源码,我们知道每个Activity都有一个Looper,所以主线程在接收Message是不需要调用Looper.prepare()和Looper.loop(),但是非主线程是不带Looper的,当非主线程要接收来自主线程的消息是就需要调用Looper.prepare()和Looper.loop()。
package com.test.looper;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
public class MainActivity extends Activity {
private LooperThread looperThread;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
looperThread = new LooperThread();
looperThread.start();
looperThread.getHandler().sendEmptyMessage(1);
}
class LooperThread extends Thread {
private Handler mHandler;
private final Object mSync = new Object();
public void run() {
Looper.prepare();
synchronized (mSync) {
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
Log.d("CYQ", "--->" + msg);
}
};
mSync.notifyAll();
}
Looper.loop();
}
public Handler getHandler() {
synchronized (mSync) {
if (mHandler == null) {
try {
mSync.wait();
} catch (InterruptedException e) {
}
}
return mHandler;
}
}
public void exit() {
getHandler().post(new Runnable(){
public void run() {
Looper.myLooper().quit();
}});
}
}
}
注意一下几点:
1、new Handler()必须在子线程的run方法中,否则不是子线程的Handler
2、在getHandler方法中,加入同步防止线程start了,但是并没有run结束,若此时直接返回mHandler会是一个null,源码中有更稳定的实现。