转载请注明出处:http://blog.csdn.net/zhouli_csdn/article/details/45668285
安卓消息处理类:
Looper、Handler、MessageQueue、Message、ThreadLocal、ThreadLocal.Values、HandlerThread。
Looper:
线程默认是没有消息循环的,要为一个线程创建一个消息循环通过调用prepare(),然后在调用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();
}
}
那么到这里你肯定会想安卓的主线程并没有prepare和loop也可以创建Handler,处理消息循环。这是因为安卓在创建主线程的时候已经为我们添加了消息循环。
那么Looper如何管理每一个线程对应的一个looper的呢?
public final class Looper {
// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;
private Printer mLogging;
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));
}
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
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;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycle();
}
}
public static Looper myLooper() {
return sThreadLocal.get();
}
下面通过图解讲解上面的过程:(prepare调用threadLocal的get的set方法)
Handler类:
构造函数:
1)Handler handler = new Handler(),内部会调用 public Handler(Callback callback, boolean async)方法,
将Handler的成员变量mLooper和mQueue赋值为当前线程的looper对象和对应的消息队列,如果当前线程没有looper会抛出异常。
2)Handler handle = new Handler(Looper looper),内部会调用public Handler(Looper looper, Callback callback, boolean async),将参数的looper对象传递给handler的mHandler对象,mQueue对象赋值。通过此方法可以在其它线程中为主线程创建Handler,例如:new Handler(Looper.getMainLooper());
handler的sendMessage()方法,在内部会将handler对象赋值为Message的mTarget中,然后调用mQueue将消息发送到线程的消息队列中。
Message类:
Message类内部会保存一个Handler对象mTarget。
Looper的loop方法,取出消息,然后调用Message对象中的handler的dispatchMessage方法,dispatchMessage根据callback是否为空执行handleMessage方法。
流程图如下:
HandlerThread是一个可以简单创建一个进行消息处理的线程类。
总结:
1)Thread最多与一个looper建立联系。
2)一个looper有且仅有一个MessageQueue
3)一个handler只能与一个looper关联
4)一个Message只能与一个handler关联
这四个一对一的关系使得消息发送和处理得到正确的相应。