Looper对象是线程的消息循环处理器,每个线程只能有一个Looper对象。Looper内部有一个消息队列MessageQueue,所有线程的消息都存放在这个队列中。新创建一个线程时,系统并不会马上为这个线程创建一个Looper对象,需要程序自己创建。Android在启动时,为主线程创建一个Looper对象。
Looper类的主要成员变量和方法:
public final class Looper{
static final ThreadLocal<Looper> sThreadLocal=new ThreadLocal<Looper>();//通过将需要保存的对象和线程id关联在一起的方式实现了线程本地存储的功能
private static Looper sMainLooper; //主线程looper
final MessageQueue mQueue;//消息队列
final Thread mThread;
private static void prepare(boolean quitAllowed){...}//创建looper实例
public static void prepareMainLooper(){...} //创建主线程looper对象
public static Looper getMainLooper(){...}//返回主线程的Looper对象
public static void loop(){....} //循环
}
每个线程只能有一个Looper类的实例对象,并把它保存在 ThreadLocal中,如果一个线程中多次调用prepare()方法将会抛出异常。
private static void prepare(boolean quitAllowed){
if(sThreadLocal.get()!=null){
throw new RuntimeException(“...”);
}
sThreadLocal.set(new Looper(quitAllowed));
}
创建主线程的代码在Framework中,应用层不能直接取得主线程的Looper对象。因此,Android将获得主线程Looper对象的方法放在了Looper类中:
public static Looper getMainLooper(){
synchronized(Looper.class){ //这里使用synchronized进行同步处理,防止两个线程同时获取主线程的looper。
return sMainLooper;
}
}
接下来我们再看loop()方法
public static void loop(){
final Looper me=myLooper();
....
final MessageQueue queue=me.mQueue;
...
for(;;){
Message msg=queue.next();//取一条消息,没有消息会阻塞
if(msg==null){
return; //msg等于null表示接到了退出的请求
}
....
msg.target.dispatchMessage(msg);//分发消息
....
msg.recycleUnchecked();
}
}
loop()中使用无限for循环从消息队列中读取数据,如果没有消息则阻塞,如果msg==null则退出,否则分发消息。