您的位置:首页 > 移动开发 > Android开发

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

2015-07-02 16:59 337 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  源码 信息处理