Handler message mechanism

Source: Internet
Author: User

MessageQueue code: HTTP://GREPCODE.COM/FILE_/REPOSITORY.GREPCODE.COM/JAVA/EXT/COM.GOOGLE.ANDROID/ANDROID/5.1.1_R1/ Android/os/messagequeue.java/?v=source

Handler code:

http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/os/ Handler.java/?v=source

Looper Code:

http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/os/ Looper.java/?v=source

The message mechanism of handler mainly involves three aspects:

    1. Message sender;
    2. Message Queuing;
    3. The message processing loop operation.

Message Sent:

 Public Final Boolean More ... sendMessage (Message msg)    {        returnsendmessagedelayed (msg, 0);    }

Go down:

 Public Final Boolean Long Delaymillis)    {        if (Delaymillis < 0) {            = 0;        }         return sendmessageattime (msg, systemclock.uptimemillis () +   delaymillis);    }

Finally come here:

 Public BooleanMore ... sendmessageattime (Message msg,LongUptimemillis) {MessageQueue Queue=Mqueue; if(Queue = =NULL) {runtimeexception e=NewRuntimeException ( This+ "Sendmessageattime () called with no Mqueue"); LOG.W ("Looper", E.getmessage (), E); return false; }        return enqueuemessage (queue, MSG, uptimemillis); }

Call Enqueuemessage to insert a message in the message queue, and in Enqueuemessage total, the msg.target is set to the current handler object.

Private Boolean Long Uptimemillis) {    this;     if (masynchronous) {        msg.setasynchronous (true);    }     return  queue.enqueuemessage (msg, uptimemillis);}

Insert the message into the message queue as follows. And it can be seen clearly that Message Queuing is a linear linked list structure.

BooleanEnqueuemessage (Message msg,LongWhen ) {    if(Msg.target = =NULL) {        Throw NewIllegalArgumentException ("Message must has a target.")); }    if(Msg.isinuse ()) {Throw NewIllegalStateException (msg + "This message was already in use.")); }    synchronized( This) {        if(mquitting) {illegalstateexception e=Newillegalstateexception (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; BooleanNeedwake; 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 has to wake//Up the event queue unless there are a barrier at the head of the queue//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.nextPrev.next =msg; }        //We can assume mptr! = 0 because mquitting is false.        if(Needwake) {nativewake (mptr); }    }    return true;}

Each thread can run only one Looper object, and when the Looper is created, a message queue MessageQueue is created internally, and Looper must first be prepare (). Loop again to MessageQueue the message queue for the traversal loop operation.

 Public Static voidLoop () {FinalLooper me =Mylooper (); //If the Looper object is empty, the prompt must be created at the current thread through Looper.prepare ()        if(Me = =NULL) {            Throw NewRuntimeException ("No Looper; Looper.prepare () wasn ' t called on the This thread. "); }        //If looper is not NULL, take out Message Queuing        FinalMessageQueue queue =Me.mqueue;        Binder.clearcallingidentity (); Final LongIdent =binder.clearcallingidentity (); //Traverse Message Queue         for (;;) {Message msg= Queue.next ();//might block            if(msg = =NULL) {                //No message indicates that the message queue is quitting. //No message interrupt operation                return; }            //----------------The queue is not a null operation----------------//This must is in a local variable with case a UI event sets the loggerPrinter logging =me.mlogging; if(Logging! =NULL) {logging.println (">>>>> dispatching to" + Msg.target + "" +Msg.callback+ ": " +msg.what); }            //----------------queue is not NULL, distributing data out----------------msg.target.dispatchMessage (msg); if(Logging! =NULL) {logging.println ("<<<<< finished to" + Msg.target + "" +msg.callback); }            //Make sure that during the course of dispatching the//The identity of the thread wasn ' t corrupted.            Final LongNewident =binder.clearcallingidentity (); if(Ident! =newident) {LOG.WTF (TAG,"Thread identity changed from 0x" + long.tohexstring (Ident) + "to 0x" + Lon                        G.tohexstring (newident) + "while dispatching to" + Msg.target.getClass (). GetName () + "" + Msg.callback + "what=" +msg.what);        } msg.recycleunchecked (); }    } 

Loop through and distribute messages out msg.target.dispatchMessage (msg):

/*** Handle system messages here. * First, if the message's callback is not empty, it calls Handlecallback processing. Otherwise, it determines whether the Handler mcallback is empty or not, and calls its Handlemessage method. If it is still empty, call Handler's own handlemessage, which is the method we override when we create the Handler */ Public voidDispatchMessage (Message msg) {if(Msg.callback! =NULL) {handlecallback (msg); } Else {        if(Mcallback! =NULL) {            if(Mcallback.handlemessage (msg)) {return; }        }        //Callback Handler Handlemessage (msg) method to receive data handlemessage (msg); }}

Well, write this first, and take the time to see it tomorrow, and try to minimize the mistakes.

Handler message mechanism

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.