Android中被使用的消息队列的代码在目录\sources\android-22\android\os下,主要涉及到以下几个类文件
Handler.java 在这里面代表一个消息实体对象
Looper.java 主要用来监听MessageQueue的消息,他存放于ThreadLocal中
Message.java 主要用来处理消息的发送,以及响应消息的业务处理
MessageQueue.java 是一个单独的线程,可与Looper整合,实现一个完全独立的消息处理机制
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; }
Looper.java public final class Looper { final MessageQueue mQueue; //消息队列 final Thread mThread; //Looper联系的线程 public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { //先会检查是否有Looper,若有则抛出异常,没有的话则创建一个Looper实例保存起来 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); } public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } //在这个线程中运行消息队列,调用quit()停止 public static void loop() { ... final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // 从消息队列中取出一条消息 if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg); //交给msg的handler分发消息处理 ... } //取出当前线程的Looper,返回空则表示当前线程没有Looper public static Looper myLooper() { return sThreadLocal.get(); } }
Handler.java public class Handler { //定义Callback接口 public interface Callback { public boolean handleMessage(Message msg); } //子类要实现的消息处理方法 public void handleMessage(Message msg) { } * Handle system messages here. */ public void dispatchMessage(Message msg) { //分发信息 if (msg.callback != null) { //若指定了msg.callback,则由它处理 handleCallback(msg); } else { if (mCallback != null) { //若指定了Handler.mCallback,则由它处理 if (mCallback.handleMessage(msg)) { //调用mCallback接口的实现方法 return; } } handleMessage(msg); 最后才调用Handler自身重载的handleMessage方法 } } 分发消息函数中,消息先会检查自身有没有处理自身的回调Runnable,若有则由它处理,若没有则会检查该handler有无自身的回调处理,若有则调用,若没有则调用自身重载的handleMessage方法 //Handler的生成总是和它当前所处线程有关的,如果当前线程中没有一个Looper,则会报错,UI线程中默认有产生Looper的函数 public Handler() { this(null, false); } //使用指定的Looper(可以处理那个Looper线程中的消息),不用默认的从当前线程中取出Looper public Handler(Looper looper) { this(looper, null, false); } ... }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索int
, 函数
, new
, null
, synchronized
消息队列
android 消息推送机制、android消息处理机制、android 消息机制、android消息传递机制、android消息分发机制,以便于您获取更多的相关知识。
时间: 2024-09-24 18:59:05