class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
public final class Message implements Parcelable {
public int what;
public int arg1;
public int arg2;
public Object obj;
long when;
Bundle data;
Handler target;
Runnable callback;
// sometimes we store linked lists of these things
Message next;
private static final Object sPoolSync = new Object();
private static Message sPool;
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 50;
... ...四个公有变量相信大家都不陌生,这里就不再介绍了。我们看到Message还有一些成员变量,比如说target,这是个Handler对象,target可以通过set方法或者obtainMessage等方式设置,一旦设置了Target,这个message就被绑定到一个具体的handler上了,然后message内部即可调用sendToTarget方法将message交给绑定的Handler进行处理,内部也调用的是sendMessage:public void sendToTarget() {
target.sendMessage(this);
}
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
sPoolSize--;
return m;
}
}
return new Message();
}recycle方法又会将用完的Message回收: public void recycle() {
clearForRecycle();
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}sendMessage方法调用了sendMessageDelayed方法,延时设为0,继续跟源码:public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}先是判断延时参数的合法性,然后调用了sendMessageAtTime方法,果断跟进去看看:public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}跟到这一步,我们发现了一个没见过的变量,mQueue,查看该变量定义:...... final MessageQueue mQueue; final Looper mLooper; final Callback mCallback; ......原来mQueue是一个消息队列,那么消息队列是怎么初始化的呢?我们找到Handler的一个构造器:
public Handler(Callback callback, boolean async) {
... ...
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can‘t create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}原来mQueue是Looper的成员变量,这个构造器通过Looper.myLooper方法返回了一个与当前线程绑定的Looper对象,进而获取到与Looper绑定的MessageQueue。这是Looper的构造器:private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mRun = true;
mThread = Thread.currentThread();
}既然我们知道了mQueue的来历,那么我们继续随着上面的思路跟进吧!刚才我们通过跟踪sendMessage源码发现内部最终调用了sendMessageAtTime方法,而这个方法又调用了enqueueMessage方法,从名字上能看出,该方法是将消息出队的方法,等等。。消息出队不应该是消息队列的方法么?怎么Handler也有?别急,我们查看enqueueMessage方法源码:private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;//我觉得这里应该判断target是否已经存在,如果存在就没必要设置了吧?
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
final boolean enqueueMessage(Message msg, long when) {
if (msg.isInUse()) {//消息是否正在使用
throw new AndroidRuntimeException(msg + " This message is already in use.");
}
if (msg.target == null) {//是否绑定handler
throw new AndroidRuntimeException("Message must have a target.");
}
boolean needWake;
synchronized (this) {
if (mQuiting) {
RuntimeException e = new RuntimeException(
msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
return false;
}
msg.when = when;
Message p = mMessages;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
}
if (needWake) {
nativeWake(mPtr);
}
return true;
}跟到这里终于明白了,这个MessageQueue是通过mMessages变量来记录当前待处理的消息,通过Mesage的发送的时间进行排序(调用msg.next)。public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn‘t called on this thread.");
}
final MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
... ...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
return;
}
... ...
msg.target.dispatchMessage(msg);
... ...
msg.recycle();
}
}这个方法首先获取到消息队列的一个引用,然后在一个死循环中反复调用消息队列的出队方法(next)获取到下一个待处理的消息的引用,然后调用该消息所绑定的handler的dispatchMessage方法分发消息,最后将该消息回收。我们跟踪Handler的dispatchMessage方法: public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}既然是分发消息的方法,那必然会根据消息的类型做出不同的处理,这个方法正是根据Message对象是否携带了callback,如果携带了callback那就执行handleCallback方法,callback之前分析Message类的时候已经知道是一个Runnable的对象了。下面我们看看handleCallback是什么实现的: private static void handleCallback(Message message) {
message.callback.run();
} 一目了然!直接调用callback的run方法。之前我们用post方法发送消息时携带的Runnable对象在Handle内部被转化为一个Message:private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
public interface Callback {
public boolean handleMessage(Message msg);
}
【安卓笔记】Handler,Looper,MessageQueue,Message源码分析,布布扣,bubuko.com
【安卓笔记】Handler,Looper,MessageQueue,Message源码分析
原文:http://blog.csdn.net/chdjj/article/details/20151655