Looper
Looper的作用是在一个线程(thread)中循环取出消息并分发到对应的处理函数中去。
线程通常是没有与之相关联的消息looper的,通过这个类则可以实现这一功能:
1、在目的线程中调用prepare,创建一个looper并关联之
2、调用loop使looper开始工作,开始消息的分发工作
looper与所处理的消息大部分的交互都是通过 Handler这个类来实现的。
典型的用法:
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 LooperThread().start();
一、prepare函数
/** 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() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
sThreadLocal的定义:
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
ThreadLocal是jdk中的一个线程局部变量类,这里表示sThreadLocal是一个线程局部变量,即线程中均保持其独立的副本。
而prepare中作做的则是创建了一个新的Looper并把这个对象赋予了线程局部变量sThreadLocal。
二、loop函数
/**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
public static void loop() {
Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
while (true) {
Message msg = queue.next(); // might block
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
long wallStart = 0;
long threadStart = 0;
msg.target.dispatchMessage(msg);
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();
}
}
}
此函数的工作就是不停地从线程局部变量sThreadLocal中不断地取出消息,并分发,我们再来看一下分发函数:
//Handler.java
public void dispatchMessage(Message msg) {
if (msg.callback != null) { //如果msg自带有callback
handleCallback(msg); //调用自带的callback
} else { //否则
if (mCallback != null) { //如果handler自带有callback
if (mCallback.handleMessage(msg)) { //调用handler自带的callback
return;
}
}
handleMessage(msg); //调用关联handler的handleMessage
}
}