Android messaging mechanism and Message/messagequeue/handler/looper

Source: Internet
Author: User

Overview* Message: Messages. Messages can contain simple data, object and bundle, and can contain a runnable (which can actually be considered a callback). * MessageQueue: Message Queuing for looper threads to consume messages. * Looper: Used to loop through the message, a thread in conjunction with a Looper to implement messages loop processing. The main thread of the Android app contains the Looper. * Handler: is responsible for sending a message to the current Looper thread, and implementing a callback for how to handle it, which can be placed in the implementation of the callback interface or in the run in the runnable passed in. Message Processing Flow1. Mainthread (a looper thread) is running, there are MessageQueue in the thread that can interact and loop through the message in MessageQueue. 2. Create a MessageQueue binding in Mainthread that is handler,handler with the current thread looper. 3. Send a message to MessageQueue via Handler.sendmessage (Message msg), wait for execution, send an empty message to MessageQueue via Handler.post (Runnable R), The empty message is appended with runnable, pending execution. 4. Mainthread polls the MessageQueue message and throws it to the message corresponding to the handler execution. Message * It is best to create a Message object from Message.obtain (), which is more efficient to create from the message pool.   Source Analysis Public final class Message implements parcelable{     public int what;//user-defined identification code     & nbsp;public int arg1; Used to store simple data so that messages can be done without using Object/bundle.      public int arg2;     public Object obj; Object-type data.      public Messenger replyto;      bundle data; The final processing of complex message data      //message is in two cases:     handler target; 1) The message is processed by the target of message (Handler), specifically HANDELR implementation handlemessage ().      runnable callback; 2) The message is processed by the callback (Runnable) of the empty message, which is to discard message and call run () directly.      private static final Object Spoolsync = new Object (); Lock used by message pool      private static message SPool; The available message objects that are removed from the message pool. Each time it is taken, a usable one is placed here.      private static int spoolsize = 0; Number of currently available message objects      private static final int max_pool_size = 50;  //Pool storage      messAge Next; Implementing a linked-list message pool       //fetching an available message object from the message pool      public static message obtain () {    & nbsp     synchronized (Spoolsync) {            if (sPool! = null) {                Message m = spool;                SPool = M.ne xt;                M.next = null;             & nbsp   spoolsize--;                return m;          &NB Sp }         }          return new Message ();    &NBSP;}&NBSP;&N Bsp    //Copy from existing message and return to     public static message obtain (message orig) {        Messa GE m = Obtain ();        M.what = orig.what;        M.ARG1 = orig.arg1;        M.ARG2 = orig.arg2;        m.obj = orig.obj;        M.replyto = orig.replyto;        if (orig.data! = null) {            M.data = new Bundle (orig.data);       }        M.target = orig.target;      &N Bsp M.callback = orig.callback;         return m;   }      //Send Message &nbs p;     public void Sendtotarget () {          target.sendmessage (this);// call is Handler's sendMessage ()}//Message reclaim public void Recycle () {clearforrecycle ();//Clears all information about the Message object synchronized (Spoolsyn                    c) {if (Spoolsize < max_pool_size) {next = SPool;//The next available message is current SPool (available) SPool = this; The currently available message is the spoolsize++ of the message object that is releasing the purge; Increment of Available Objects}}}} MessageQueue* Holding the list of messages to is dispatched by a Looper. * You cannot add a message directly to Looper's MessageQueue, you need to pass handler. * The MessageQueue of the current thread can be obtained by Looper.myqueue (). Handler* Create a handler will be bound to the current thread/messagequeue, after which handler can send a message and runnable to MessageQueue, waiting for polling execution. * Send a Message:sendmessage (Message m).  * Send a Runnable:post (Runnable R). public class handler{//Custom Handler must implement this method for processing the message public voidHandlemessage(Message msg) {}//Specifies a class public interface that implements the Callback interface Callback {public booleanHandlemessage(Message msg); }//constructor///By default, Handler will be associated to the current thread's Looper, if there is no Looper, throw exception public Handler (Looper Looper,Callback callback/* equivalent to specifying the Handlemessage () function */, Boolean async) {mlooper=looper; mqueue=looper.mqueue; Mcallback =callback;masynchronous = async; Public final Message Obtainmessage () {return Message.obtain (This)}//obtain//---------------of the message directly invoked ------------------------------------------------     // send message to MessageQueueHandler.sendxxx Call this method public boolean sendmessageattime (Message msg,long uptimemillis) {MessageQueue queue          = Mqueue;     Return Enqueuemessage (Queue,msg,uptimemillis);        Private Boolean enqueuemessage (MessageQueue queue, Message msg, long uptimemillis) {msg.target = this;        if (masynchronous) {msg.setasynchronous (true);}     Return Queue.enqueuemessage (msg, uptimemillis); }      // ---------------------------------------------------------------     // send runnable to MessageQueueThe principle is to attach runnable to the callback of an empty message, and when the message is executed, callback is executed if callback is found. Public Final Boolean post (Runnable R) {returnsendmessagedelayed(Getpostmessage (R), 0);          } private static getpostmessage (Runnable R,object token) {Message m = Message.obtain (); M.obj = token;m.callback = r;Specifies that the callback of message is R.          Messages through SendMessage are not callback, and a message containing callback will be executed by its callback.     return m; }      // ---------------------------------------------------------------     // processing MessagesMessages in Looper are implemented by calling this function to implement the public void DispatchMessage (message msg) {if (msg.callback!=null) {Handlecallback(msg); }//Process else {handlemessage (msg) in runnable;//Call handler to process the message}} private Stati c voidHandlecallback(Message message) {Message.callback.run ();//the message is discarded and the run () is called directly instead of the new thread。 }}//End Handler () Looper  * The default thread does not contain the ability to loop through messages, and the Looper class can help threads implement message loops.  Public final class looper{static final threadlocal<looper> sthreadlocal = new threadlocal<looper> ();//Line      Thread local variables, one per Looper.     Final Message Mqueue;      Final Thread Mthread;          Private Looper (Boolean quitallowed) {mqueue = new MessageQueue (quitallowed);     Mthread = Thread.CurrentThread (); }//--------------------------------------------------------------------//preparation. Creates a Looper object for the current thread static void Prepare (Boolean quitallowed/*messagequeue can exit */) {if (Sthreadlocal.get ()!=null {/*exception, the current thread's looper already exists, one thread a looper*/} sthreadlocal.set (new Looper (quitallowed));           }//--------------------------------------------------------------------//start loop public static void loop () {          Final Looper me = Mylooper ();//When the Looper instance of the front thread is final MessageQueue queue = Me.mqueue; for (;;)               {Message msg = Queue.next (); if (msg = = null) {return;} Msg.target.dispatchMessage (msg); The message is processed by Handler msg.recycle ();           Cleans up the message and returns the message pool after emptying. }//end for}//end loop ()//--------------------------------------------------------------------public void     Quit () {mqueue.quit (false);} public Boolean isidling () {return mqueue.isidling ();}} Class end. Demo

Demo#1 sending messages
Class Someactivity
{
@Override
public void OnCreate (...) {
TestMessage ();
}

void TestMessage () {
MyHandler handler = new MyHandler ();
Or
Handler = new Handler (/*this.getmainlooper (), */New Handler.callback () {/*...*/});

Send Message
Message M1 = new Message ();
M.settarget (h);
M.sendtotarget ();

Send Runnable (the inside is actually sent a message+runnable)
Handler.post (New Runnable () {
@Override
public void Run () {
Running in the main thread
}
});
}

Class MyHandler extends handler{
@Override
public void Handlemessage (Message msg) {/*...*/}
}


Demo#2 Customizing Looper threads
public static void Testlooper ()
{
Thread tlooper = new Thread (new Runnable () {

@Override
public void Run () {
Looper.prepare ();

MyHandler h = new MyHandler ();
Send Message
H.sendemptymessage (0);
Send runnable
H.post (New Runnable () {
@Override
public void Run () {
LOG.I ("Test", "[In post Runnable]threadid:" +thread.currentthread (). GetId ()); Tlooper thread ID
}});

Looper.loop (); has been circulating. Even if there is no message
}});
Tlooper.start ();
}

ReferencesHttp://developer.android.com/reference/android/os/MessageQueue.html http://developer.android.com/reference/ Android/os/looper.html

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.