The code for the message queues used in Android is in the directory \sources\android-22\android\os, mainly involving the following class files
handler.java In this case, a message entity object
looper.java is primarily used to listen for MessageQueue messages, which he stores in Threadlocal
message.java is primarily used to process message delivery, And the business process of responding to messages
messagequeue.java is a separate thread that can be integrated with looper to implement a fully independent message handling mechanism
message.java public final class message implements parcelable {
public int what; //Message type
public int arg1; //integer parameters with low cost public int arg2; Public object obj; //object type data public Notify Sender /* when messenger replyto; //message is processed package*/ int flags; //message Tags: using and asynchrony /*package*/ long when; //time when message was created /*package*/ bundle data; //additional data included with the message /*package*/ handler target; //message recipient, processor /*package*/ runnable callback; //First Use callback processing to process messages /*package*/ Message next; //next message, forming a linked list private static message Header messages in the spool; //message pool
Target in the above, The message is usually processed by the Handlemessage function of the handler subclass;
public static message obtain () { //the function that gets the message, If there's a message, get it. m, the linked list pointer moves one bit, otherwise it returns an empty message 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 () { //sends messages to the processor target.sendmessage (this); //call functions in Handler.java } }
messagequeue.java public final class messagequeue { message mmessages; //The message you are currently processing //When you need to get a message from a list, the next function is called, if there is no message in the message queue , the wait is blocked by calling the Nativepollonce function to complete the message next () {...} boolean enqueuemessage (message msg, long when) { //Add message in chronological order if (msg.target == null) { throw new illegalargumentexception ("message must have a target. "); } &NBSP;&NBSP;&NBSP;&NBSP;&Nbsp; 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 "); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;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&nbsP;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); //invoke the underlying wake function, pipe wake } } return true; &NBSP;&NBSP;&NBSP;&NBSP;}
Looper.java public final class looper { final messagequeue mqueue; //Message Queuing final Thread mThread; Looper Contact Thread public static void prepare () { prepare (true);   private static void prepare (boolean quitallowed) { //will first check whether there are looper, if any, throw an exception, if not, create a Looper instance to save if (Sthreadlocal.get () != null) { throw new runtimeexception ("only one looper may be
Created per thread "); } sThreadlocal.set (New looper (quitallowed));
&NBSP;&NBSP;&NBSP;&NBSP} public static void preparemainlooper () {
prepare (FALSE); synchronized (looper.class) { if (smainlooper != null) { throw new
IllegalStateException ("the main looper has already been prepared."); }
smainlooper = mylooper (); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP}  } //running message queues in this thread, Call quit () stop 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 (); // takes a message out of the message queue 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); //handing over to MSG handler distribution message processing   ...  } //Remove the looper of the current thread, and return null to indicate that the current thread does not have a looper public static looper mylooper () {
return sthreadlocal.get (); &NBSP;&NBSP;&NBSP;&NBSP}}
Handler.java public class handler { //Definition Callback Interface public interface callback {
public boolean handlemessage (MESSAGE&NBSP;MSG); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP} //subclass to implement the message processing method public void handlemessage (message msg) {
&NBSP} * handle system messages here. */ public void dispatchmessage (Message msg ) { //Distribution Information if (msg.callback != null) { // If Msg.callback is specified, it is processed by the &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; handlecallback (msg); } else { if (mcallback != null) { //if Handler.mcallback is specified, it handles if (Mcallback.handlemessage (msg)) { // How to invoke the implementation of the Mcallback interface
return; } } handlemessage (msg); the last call to handler itself overload Handlemessage method } &nbSP;} Distribution Message function, the message will first check whether it has handled its own callback runnable, if it is handled by it, if not it will check whether the handler has its own callback processing, if there is a call, If there is no Handlemessage method that calls itself overloaded //handler is always associated with its current thread, and if there is not a looper in the current thread, an error is generated. The default in the UI thread is the function that produces Looper public handler () {
this (Null, false); } //using the specified Looper (you can handle the messages in that Looper thread), Do not remove the default from the current thread Looper public handler (looper looper) {
this (Looper, null, false); } }