Android 消息处理源代码分析(1)

Android 消息处理源代码分析(1)





在Android中,通常被使用的消息队列的代码在文件夹\sources\android-22\android\os下,涉及到下面几个类文件

Handler.java

Looper.java

Message.java

MessageQueue.java

Message.java
public final class Message implements Parcelable { public int what; //消息种类 public int arg1; //低开销的整型參数 public int arg2; public Object obj; //Object型数据 public Messenger replyTo; //消息处理完后通知给发送者 /*package*/ int flags; //消息标记:正在使用和异步等 /*package*/ long when; //消息创建时的时间 /*package*/ Bundle data; //消息附带的额外数据 /*package*/ Handler target; //消息接受者,处理者 /*package*/ Runnable callback; //优先使用回调处理来处理消息 /*package*/ Message next; //下一个消息。形成链表 private static Message sPool; //消息池中的头消息 上面中的target,通常由又一次实现的Handler子类的handleMessage函数来处理消息 public static Message obtain() { //获取消息的函数,假设有消息的话则获取出来m,链表指针移动一位,否则则返回一条空消息
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
} public void sendToTarget() { //发送消息给处理者
target.sendMessage(this); //调用Handler.java中的函数
} }
MessageQueue.java
public final class MessageQueue { Message mMessages; //当前要处理的消息 //当须要从链表中获取一个消息时。就会调用next函数,若消息队列中没有消息,则会堵塞等待,通过调用nativePollOnce函数来完毕
Message next() {...} boolean enqueueMessage(Message msg, long when) { //按时间顺序加入消息
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
} synchronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
msg.recycle();
return false;
} msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
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 {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
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;
} // We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr); //调用底层唤醒函数,管道唤醒
}
}
return true;
}
上一篇:Unity3d外包(北京)公司(长年承接U3D外包)


下一篇:本地语音识别开源软件pocketsphinx调试总结