从字面上理解,Looper可以形容为管家负责管理一个消息队列,message就是需要传递的消息,handler就是处理的意思。Looper中有一个message队列,里面存储着一个个待处理的message,而message中有一个handler,handler类封装了很多琐碎的工作。
class OneThread extends Thread
{
public void run()
{
Looper.prepare();
.......
Looper.loop();
}
}
线程2:
{
.............
new OneThread().start();
}
线程1中执行两个方法,调用prepare方法以及loop方法进入消息循环
public static final prepare () {
if (threadLocal.get != null) {
throw new RuntimeException("only one looper may be created per thread");
}
threadLocal.set(new looper());
}
private static final ThreadLocal threadLocal = new ThreadLocal();
ThreadLocal 是Java中的线程局部变量类,全名是Thread Local Variable。该类有两个关键的函数:set:设置调用线程的局部变量
get:获取调用线程的局部变量
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
while(true) {
Message msg = queue.next();
if (msg == null) {
{if (msg.target == null)
{
return;
}
msg.target.dispatchmessage(msg);
msg.recycle();
}
}
}
loop方法中myLooper()方法返回保存在threadLocal中的Looper对象。looper对象内部封装了一个消息队列,通过next()方法又取出其中的消息,消息里的target是Handler类型,最后调用Handler的dispatchMessage函数处理。
public static final Looper myLooper() {
return (Looper)threadLocal,get();
}
返回保存在threadLocal中Looper对象
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);//post方法传递的Runnable参数
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
dispatchmessage定义了一套消息处理的优先级机制:
1.Message如果自带了callback处理,则交给callback处理 2.Handler如果设置了全局的mCallback,则交给mCallback处理 3.否则该消息交给Handler子类实现的HandleMessage处理。
我们可以知道消息循环机制的核心就是Looper,因为Looper持有了MessageQueue的对象,并且可以被一个线程设为该线程的一个局部变量,我们可以这么认为这个线程通过Looper拥有了一个消息队列。而Handler的用处就是封装了消息发送和消息处理的方法,在线程通信中,线程可以通过Handler发送消息给创建Handler的线程,通过Looper将消息放入进入消息接收线程的消息队列,等待Looper取出消息并在最后交给Handler处理具体消息。
Looper构造方法:
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
构造一个消息队列,得到当前线程的Thread对象。
不知道大家有没有发现我们在子线程和UI线程之间通讯实例化Handler时,并不需要Looper.perpare()来初始化一个Looper对象和Looper.loop()来启动消息循环!
public final class ActivityThread {
public static final void main(String[] args) {
......
Looper.prepareMainLooper();
......
ActivityThread thread = new ActivityThread();
thread.attach(false);
......
Looper.loop();
......
thread.detach();
......
}
}
Activity在构造过程中已经对Looper进行了初始化并且建立了消息循环。Android应用程序进程在启动的时候,会在进程中加载ActivityThread类,并且执行这个类的main函数,应用程序的消息循环过程就是在这个main函数里面实现的。
总之一个线程只有一个Looper对象,一个对象持有一个messageQueue,当调用Looper.prepara()方法时,Looper就与当前线程关联起来,而Handler是在当前创建的所以也会与当前线程关联,这样Looper就与Handler相关联。这很关键,决定着消息在哪个线程中处理!纯粹是为了整理自己学习的知识,欢迎大家指点