Android Message Queuing and Looper

Source: Internet
Author: User

1. What is Message Queuing

Message Queuing corresponds to the MessageQueue class in Android, as the name implies, a large number of messages (message) are stored in the message queue

2. What is a message

Messages (message) represent an action (what) or a string of actions (Runnable), two of which use Message:handler and Messenger

3. What is handler and Messenger

Handler everyone knows that it is primarily used to send messages in the thread to notify the UI threads to update the UI. Messenger can be translated as Messenger, can implement interprocess communication (IPC), Messenger takes a single thread to handle all messages, and communication between processes is done by sending messages, it feels like aidl can not directly call the other side of the interface method (specifically to be verified), This is the main difference between it and aidl, which means that Messenger cannot handle multiple threads, and all calls are executed serially in one thread. The typical code for Messenger is this: New Messenger (service). Send (msg), which essentially calls the SendMessage method of handler.

4. What is Looper

Looper is the meaning of the loop, which is responsible for taking the message out of the message queue and handing it over to the target processing

5. What is the difference between a thread and a looper?

If a thread does not have a looper, there is no message queue and the message cannot be processed, and handler cannot be used inside the thread. This is why creating a handler inside a child thread will result in an error: "Can ' t create handler inside thread that have not called looper.prepare ()", the specific reason is analyzed below.

6. How do I make a thread looper to use handler properly?

Add the following two sentences to the run method of the thread:

Looper.prepare ();

Looper.loop ();

We don't have to do this, there are ready-made, Handlerthread is a thread with Looper.

To create a Handler with the thread's looper, it's simple, Handler Handler = new Handler (Thread.getlooper ()), with these steps, you can create Handler in the sub-thread, okay, In fact, Android has long for us to think of this, do not have to write their own, intentservice to do all we have done, we just use the good, how to use the back to say.

The working mechanism of Message Queuing and Looper

A handler will have a looper, a looper will have a message queue, the role of Looper is to loop through the message queue, if there is a new message, the new message to its target processing. Whenever we use handler to send a message, the message is placed in the message queue, and then the Looper is taken out of the message sent to its destination target. In general, the target of a message is to send the message of the handler, so that Looper will give the message to handler processing, this time handler DispatchMessage method will be called, The general situation will eventually call handler's handlemessage to process the message, and using Handlemessage to process the message is a common way.

SOURCE Analysis

1. Handler the process of sending messages
Publicfinalboolean sendMessage (Message msg) {returnsendmessagedelayed (MSG, 0); } Publicfinalboolean sendmessagedelayed (Message msg,LongDelaymillis) { if(Delaymillis < Span>0) {Delaymillis= 0; } returnSendmessageattime (MSG, systemclock.uptimemillis () +Delaymillis); } Publicboolean 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); Returnfalse; } returnenqueuemessage (Queue, MSG, uptimemillis);} Privateboolean enqueuemessage (MessageQueue queue, Message msg,LongUptimemillis) {Msg.target= This; if(masynchronous) {msg.setasynchronous (true); } //here msg is added to Message Queuing queuereturnqueue.enqueuemessage (msg, uptimemillis);} 
working process of 2.Looper
Publicstaticvoid Loop () {FinalLooper me =Mylooper (); if(Me = =NULL) {thrownew runtimeexception ("No Looper; Looper.prepare () wasn ' t called on the This thread. "); }     //To remove a message queue from the Looper    FinalMessageQueue queue =Me.mqueue; //Make sure the identity of the the the the The local process,//And keep track of the What, identity token actually is.binder.clearcallingidentity (); Finallong Ident=binder.clearcallingidentity ();//dead loop, loop fetch message, no new message will block     for (;;) {Message msg= Queue.next ();//might block will be blocked here, if there are no new messages        if(msg = =NULL)         {         //No message indicates that the message queue is quitting.            return; }         //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); } //give the message to target, the target is the handler type.msg.target.dispatchMessage (msg);if(Logging! =NULL) {logging.println ("< finishedtospan> + Msg.target +" "+ msg.callback);} //Make sure that during the course of dispatching the//The identity of the thread wasn ' t corrupted.Finallong newident =binder.clearcallingidentity ();if(Ident! =newident) {LOG.WTF (TAG,"Thread identity changed from 0x" + long.tohexstring (ident) + ' to 0x ' + long.tohexstring (newident) + "while dispatching to "+ Msg.target.getClass (). GetName () +" "+ Msg.callback +" what= "+msg.what); } msg.recycle (); } }                        
3.Handler How to process messages
/*** Subclasses must implement this to receive messages.*/publicvoid handlemessage (Message msg) {}/*** Handle system messages here.*/publicvoid DispatchMessage (Message msg) {if(Msg.callback! =NULL) { //This method is simple and calls Msg.callback.run () directly;handlecallback (msg);} Else { //if we set up callback, the message will be processed by callback.if(Mcallback! =NULL) { if(Mcallback.handlemessage (msg)) {return; } } //otherwise the message will be handled here, which is the most common way we handle it.handlemessage (msg);} } 

Let's see what Msg.callback and Mcallback are.

/*package*/Runnable callback;

Now it is very clear, Msg.callback is a runnable, when will set this callback:handler.post (runnable), I believe we all use this method

 /**   @param   msg A {  @link   Android.os.Message Message} object*   @return   */ publicinterface Callback {publicboolean handlemessage (Message msg);}  final  Callback Mcallback; 

And Mcallback is an interface, you can set Handler Handler = new Handler (callback), what is the meaning of this callback, the code inside the comment has been said, So you don't have to create handler subclasses but still handle the message, I'm afraid the usual way is the new one handler and then override its Handlemessage method to process the message, from now on, we know that Subclasses that do not create handler can also process messages. To say a word, why create handler sub-class is not good? This is because the class also occupies space, one application class is too many, the space will become larger, that is, the application will consume more memory.

Handlerthread Introduction
=synchronized (this ==-1

Handlerthread inherits from thread, which creates a looper for itself within the run method, is different from the normal thread on Handlerthread, and cannot perform common background operations and can only be used to process new messages. This is because Looper.loop () is a dead loop and your code is not performing at all, but it seems like you can put your code before Super.run (), but it doesn't seem to be the mainstream, so it's not recommended.

Intentservice Introduction

 publicvoid onCreate () { //  Todo:it would is nice to having an option to hold a partial wakelock  //  during processing, and to has a static StartService (Context, Intent)  // Span style= "color: #008000;" > method that would launch the service & hand off a wakelock.  super  .oncreate (); Handlerthread thread  = new  handlerthread ("intentservice[" + Mname + "]" Span style= "color: #000000;" >); Thread.Start (); Mservicelooper  = Thread.getlooper (); Mservicehandler  = new   Servicehandler (mservicelooper);}  

Intentservice inherits from the service, it is an abstract class, it is created when the new a handlerthread and Servicehandler, with it, you can use Intentservice to do some of the higher priority task , Intentservice will not be easily killed by the system. Using Intentservice is also very simple, first startservice (intent), then Intentservice will wrap your intent into a message and send it through Servicehandler, Then Servicehandler will call Onhandleintent (Intent Intent) to handle this message,onhandleintent (Intent Intent) Intent is the Intent,ok in your StartService (intent), now all you need to do is derive a subclass from Intentservice and override the Onhandleintent method, Then you just have to do different things for different intent, and Intentservice will stop automatically when things are done. Therefore, Intentservice is a time-consuming operation in addition to thread and asynctask, and it is not easy to be killed by the system, it is recommended that the key operation is Intentservice.


Handler common errors in child threads

 PublicHandler (Callback Callback,Booleanasync) { if(find_potential_leaks) {Finalclass< span>extendshandler< Klass =getclass ();if((Klass.isanonymousclass () | | klass.ismemberclass () | | klass.islocalclass ()) &&(Klass.getmodifiers ()& modifier.static) = = 0) {LOG.W (TAG,"The following Handler class should be static or leaks might occur:" +klass.getcanonicalname ()); } } //gets the looper of the current threadMlooper =Looper.mylooper ();//the root cause of the error is: The current thread is not looperif(Mlooper = =NULL) {thrownew runtimeexception ("Can ' t create handler inside thread that have not called looper.prepare ()"); } mqueue=mlooper.mqueue; Mcallback=callback; Masynchronous=Async;} 

Avoid this error: Use handler on the UI thread or add Looper to the child thread.

Android Message Queuing and Looper

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.