Android message processing mechanism source code detailed analysis tutorial

Source: Internet
Author: User
Tags message queue prepare prev

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);    &nbsp           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}    &nbsp}    //running message queues in this thread, Call quit () stop    public static void loOP ()  {   &nbsp ...     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    &nbsp ...   &nbsp}     //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);     }    }


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.