先看一个Looper使用范例:
class LooperThread extends Thread{
public Handler mHandler;
public void run(){
Looper.prepare();
mHandler = new Handler(){
public void handleMessage(Message msg){
//处理消息
}
};
Looper.loop();//进入主循环
}
}
这段代码有三个步骤:
1.Looper的准备工作(prepare)
2.创建handler
3.Looper开始动行(loop)
这里会有些疑问,Looper的对象是怎么创建的;handler是如何把message传给MessageQueue的。
查看Looper代码,里面有个非常重要的成员变量
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
这是一个静态常量,一旦import了Looper,sThreadLocal就会构建完毕。ThreadLocal对象是一种特殊的全局变量,因为它的“全局”性只限于自己所在的线程,而外界所有线程无法访问它,这也说明了每个线程的Looper都是独立的。在Looper.prepare中sThreadLocal会创建一个Looper对象。
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));
}
接下来创建一个Handler对象
public Handler mHandler;
mHandler = new Handler(){
public void handleMessage(Message msg){
...
}
};
handler根据构造函数跟Looper关联起来的,比如:
public Handler();
public Handler(Callback callback);
public Handler(Looper looper);
public Handler(Looper looper,Callback callback);
这里来看下第一个构造函数
public Handler(){
...//省略部分代码
mLooper = Looper.myLooper();//还是通过sThreadLocal.get来获取当前线程中的Looper实例
...
mQueue = mLooper.mQueue;//mQueue是Looper与Handler之间沟通的桥梁
mCallback = null;
}
这样Handler和Looper,MessageQueue就联系起来了,后续handler执行Post/Send两个类型的函数时,会将消息传递到mQueue中,一旦Looper处理到这一消息,它又会从中调用Handler来进行处理。
评论 (0)