Android中的Java应用程序是靠消息驱动来工作的,大致原理就是
- 有一个小心队列,可以往这个消息队列中投递消息。
- 有一个消息循环,不断从消息队列中取出消息,然后处理
Looper类
查看源码发现开始他给出了一个小例子,告诉我们 Looper
类是如何使用的
37 * class LooperThread extends Thread {
38 * public Handler mHandler;
39 *
40 * public void run() {
41 * Looper.prepare();
42 *
43 * mHandler = new Handler() {
44 * public void handleMessage(Message msg) {
45 * // process incoming messages here
46 * }
47 * };
48 *
49 * Looper.loop();
50 * }
51 * }
我们发现它主要实现有两步
- prepare()
- looper()
prepare()方法的具体实现
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));
}
//ThreadLocal sThreadLocal = new ThreadLocal();
这里会发现ThreadLocal
类通过set()
方法设置了一个与当前线程有关的Looper
对象,而Looper
构造函数定义如下
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
所以我们可以得出以下结论:
在调用prepare的线程中,设置了一个Looper对象,这个Looper对象就保存在这个调用线程的ThreadLocal对象中。而Looper对象内部封装了一个消息队列。
looper()方法具体实现
public static void loop() {
final Looper me = myLooper(); //从ThreadLocal中将Looper对象取出,mylooer()代码自己去看源码
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue; //将queue对象取出,用来处理消息
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {
Message msg = queue.next(); // 处理消息利用Handler辅助类
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
final Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
......
}
Handler分析
Handle-Message-Looper关系解析
Looper中有一个Message队列(MessageQueue),里面存储的是一个个待处理的Message,Message中有一个Handler,这个Handler对象使用来帮助处理Message的
Handle对象有三个成员很重要
- MessageQueue //实际就是某个Looper对象的消息队列
- Looper
- Callback //回调类,用来获取消息处理状况