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();
new Thread(new Runable{
run(){
mHandler.send(msg);
}
}).start();
}
}
1、Handler有以下重要属性
final MessageQueue mQueue;
final Looper mLooper;
这两个属性都和Looper关联,直接来自于Looper 如以下
/**
* Default constructor associates this handler with the queue for the
* current thread.
*
* If there isn't one, this handler won't be able to receive messages.
*/
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();//获取当前线程关联的Looper, 常由Looper.prepare()进行关联
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}
所以我们向Handler中发送Msg或Post Runable 时 ,实质上是向关联的Looper.mQueue中添加Message对象。
而Message中主要有以下重要属性
/*package*/ Bundle data; //发送时绑定的数据
/*package*/ Handler target; //和msg绑定的Handler
/*package*/ Runnable callback; //postRunable
2、对于Looper
有一个很重要的属性
final MessageQueue mQueue;//消息队列
使用:1、执行Looper.prepare();
给当前线程绑定一个新Looper对象,包括新的序列
/** 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 final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
2、执行Looper.loop()开始循环取队列并派发消息处理
所以我们在新线程中使用Handler时就必须调用Looper.prepare()和Looper.loop()
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();
new Thread(new Runable{
run(){
mHandler.send(msg);
}
}).start();
}
}
然而为什么在主线程中而不必调用这两个方法呢?因为主线程一启动就已经执行这两个方法,所以我们常在主线程中直接就可以使用handle如下:
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
使用Handler实现异步更新UI例子synHandlerUpdateUI.zip