Handler
消息的处理者。通过Handler对象我们可以封装Message对象,然后通过sendMessage(msg)把Message对象添加到 MessageQueue中;当MessageQueue循环到该Message时,就会调用该Message对象对应的handler对象的 handleMessage()方法对其进行处理。由于是在handleMessage()方法中处理消息,因此我们应该编写一个类继承自 Handler,然后在handleMessage()处理我们需要的操作。
Looper
MessageQueue的管理者,在一个线程中,如果存在Looper对象,则必定存在MessageQueue对象,并且只存在一个Looper对象 和一个MessageQueue对象。倘若我们的线程中存在Looper对象,则我们可以通过Looper.myLooper()获取,此外我们还可以通 过Looper.getMainLooper()获取当前应用系统中主线程的Looper对象。在这个地方有一点需要注意,假如Looper对象位于应用 程序主线程中,则Looper.myLooper()和Looper.getMainLooper()获取的是同一个对象。
MessageQueue
MessageQueue顾名思义,就是消息队列,使用队的方式来管理Message,程序创建Looper对象时会在它的构造器中创建Looper对象,Looper的构造器如下:
private looper()
{
mQueue = new MessageQueue();
mRun=true;
mThread=Thread.currentThread;
}
可以看出来,我们无法通过构造器创建Looper对象,但是程序在初始化时会创建一个MessageQueue,这个MessageQueue就负责管理消息。
当我们创建出一个子线程的话,想往自己创建的MessageQueue中发送消息,也就是说想让handler正常工作,但是如果在非ui线程中是没有MessageQueue的,那么怎么样才能有呢,根据上面的代码,可以看到,当我们创建出Loopre对象时便会创建出一个MessageQueue,所以我们可以使用Looper.prepare()来创建Looper
public static final void prepare()
{
if(sThreadLocal.get()!=null)
{
throw ........
}
sThreadLocal.set(new Looper);
}
那么ThreadLocal是什么呢
ThreadLocal是什么
早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。
所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。
ThreadLocal的接口方法
ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:
void set(Object value)设置当前线程的线程局部变量的值。
public Object get()该方法返回当前线程所对应的线程局部变量。
public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
protected Object initialValue()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。
那么我们便可以理解了 sThreadLocal.set(new Looper())用一个ThreadLocal记录住Looper是哪个线程的Looper,以便用来调用
说的有点远。。。。。
当我们创建出Looper对象时,我们调用Looper.loop()方法启动它,
loop()方法是一个死循环用来不断的从MessageQueue中取出消息,并将取出的消息分给该消息对应的Handler进行处理,下面是Looper.loop()的部分源码
for(;;)
{
Message msg = queue.next();
if(msg==null)
return;
//。。。。。。。。。消息处理等等
}
归纳起来:
handler:能把消息发送给Looper管理的MessageQueue,并负责处理Looper分发的消息
Looper:一个线程只有一个Looper 负责管理MessageQueue,不断从MessageQueue中取出消息,分给对应的Handler
MessageQueue:用队的方式管理Message