Android Message Processing source code Analysis (1)
In Android, the code for Message Queuing that is commonly used is under directory \sources\android-22\android\os and involves the following classes of files
Handler.java
Looper.java
Message.java
Messagequeue.java
Message.javapublic Final class Message implements parcelable {public int; Message kind public int arg1; Low-overhead integer parameter public int arg2; public Object obj; Object type data public Messenger replyTo; Notification to sender/*package*/int flags after message processing; Message tokens:/*package*/long when in use and asynchronously; The time when the message was created/*package*/Bundle data; Additional data accompanying the message/*package*/Handler target; Message recipient, processor/*package*/Runnable callback; Prioritize using callback processing to process messages/*package*/message next; Next message, form a linked list private static Message SPool; The target in the message pool above the header message, usually by the Handlemessage function of the re-implemented handler subclass, handles the message public static message obtain () {//Gets the message function, and is removed if there is a message To M, the 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 () {//Send message to Processor target.sendmessage (this); Call the function in Handler.java}}
Messagequeue.javapublic Final class MessageQueue {Message mmessages; Messages currently being processed//when a message needs to be fetched from a linked list, the next function is called, and 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 (Msg.target = = null) {throw new Ill Egalargumentexception ("Message must has a target."); } if (Msg.isinuse ()) {throw new IllegalStateException (msg + "This message is already"); } synchronized (this) {if (mquitting) {illegalstateexception e = new Illegalstateexce Ption (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 are a barrier at the head of the 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.next Prev.next = msg; }//We can assume mptr! = 0 because mquitting is false. if (needwake) {nativewake (mptr); Call the underlying wake function, pipe wake}} return true; }
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Android Message Processing source code Analysis (1)