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中的函数
}
}
在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; }
相关文章推荐
- 从源码安装Mysql/Percona 5.5
- asp.net 抓取网页源码三种实现方法
- JS小游戏之仙剑翻牌源码详解
- JS小游戏之宇宙战机源码详解
- jQuery源码分析之jQuery中的循环技巧详解
- 本人自用的global.js库源码分享
- java中原码、反码与补码的问题分析
- PHP网页游戏学习之Xnova(ogame)源码解读(六)
- C#获取网页HTML源码实例
- PHP网页游戏学习之Xnova(ogame)源码解读(八)
- PHP网页游戏学习之Xnova(ogame)源码解读(四)
- JS小游戏之极速快跑源码详解
- JS小游戏之象棋暗棋源码详解
- 基于Android设计模式之--SDK源码之策略模式的详解
- Android游戏源码分享之2048
- C语言借助EasyX实现的生命游戏源码
- C实现的非阻塞方式命令行端口扫描器源码
- PHP网页游戏学习之Xnova(ogame)源码解读(七)
- PHP网页游戏学习之Xnova(ogame)源码解读(一)
- PHP网页游戏学习之Xnova(ogame)源码解读(九)