1.Looper类
looper是线程的消息循环处理器,每个线程只能有一个Looper对象,其内部有一个MessageQueue,所有消息都存放在这个队列中。
新创建一个线程时,系统不会为这个线程创建Looper,需要自己创建。Android在启动时,为主线程(UI 线程)创建一个looper 对象。
1.1 HandlerThread
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();//Looper类的实例必须通过prepare函数创建
synchronized (this) {
mLooper = Looper.myLooper();//通过myLooper方法获取Looper对象
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();//loop函数主要分发消息队列中的消息。
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
}
下面我们主要看下Looper类中的loop方法:
public static void loop() {
final Looper me = myLooper();
... ...
final MessageQueue queue = me.mQueue;//消息队列
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {//无线循环
Message msg = queue.next(); // might block
... ...
msg.target.dispatchMessage(msg);//分发消息
... ...
msg.recycle();
}
}
looper.loop() 就是在一个死循环中持续读取MessageQueue 中的消息并dispatch。
Handler类
public Handler(Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
... ...
mLooper = Looper.myLooper();
... ...
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
Handler主要负责消息的发送和处理。在一个线程中可以只用一个Hander对象处理所以消息,也可以使用多个。
1.构造一个Handler对象,需要两个参数,线程的Looper对象和消息处理函数,如果不指定looper,会使用当前线程的looper对象。
2.handler 对象创建时,调用的是当前线程的Looper对象作为mLooper,同时调用mQueue = mLooper.mQueue , 即当前线程的消息队列作为自己将要处理的消息队列(Handler.mQueue)。
3.并不是每个线程都默认有looper 对象,所以在创建handler对象之前,会先调用Looper.prepare(),为当前Thread 创建一个looper 对象
Handler.sendMessage ->Handler.sendEmptyMessage ->... ->Handler.enqueueMessage
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;//注意msg.target都是handler,因此在消息线程的loop函数处理消息时,msg.target.dispatchMessage会回到handler。
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
所有的发送消息接口,最后都会调用MessageQueue类中enqueueMessage函数,参数除了消息外,就是一个时间。而MessageQueue类中enqueueMessage函数只是把消息插入到消息队列中的合适位置。
总结一下:
0. 一个线程有且仅有一个looper对象,looper对象中有一个MessageQueue 作为消息队列;
1.消息机制需要一个线程环境,里面需要一个Looper对象,并且在线程的run函数中调用Looper.loop()函数;
2.函数需要一个handler来发送和处理消息。Hander要有一个Looper对象,来指定其线程,还要实现handleMessage函数。
Looper线程首先是一个Thread,由Java 标准线程变化过来:
一般的:
class LooperThread extends Thread { //继承Thread 类
public Handler mHandler; //需要一个handler对象发送处理消息
public vold run { //实现run() 方法
Looper.prepare(); //Looper线程准备阶段
mHandler = new Handler() { //初始化消息处理器
public vold handleMessage (Message msg) {
//TODO :处理消息
}
};
Looper.loop(); //Looper线程循环阶段
}
}
以上代码可知,Looper线程实际上继承了Thread 类,并实现run 方法,运行run()时:
1.调用Looper.prepare为当前thread 创建一个Looper对象(一个线程有且仅有一个looper 对象);
2.创建handler对象,将之前创建的looper 对象的MsgQueue作为自己的MsgQueue ,负责分发和处理消息;
3.调用Looper.loop()方法进入Looper线程循环阶段;
4.handler 发送消息最后调用MessageQueue类中enqueueMessage函数,就是把消息插入到消息队列中的合适位置