Handler message delivery mechanism

Source: Internet
Author: User

Introduction:

For performance tuning purposes, Android UI operations are not thread-safe, which means that if there are multiple threads concurrently manipulating the UI component, it can cause thread safety issues.

To solve this problem, Android has a simple rule: only allow the UI thread to modify the components in the acitivity, which will cause the newly-started thread to dynamically change the value of the Build property.

However, in the actual application development, it is necessary to let the newly-started thread change the attribute value of the interface component, which needs to be realized by the message passing mechanism with handler.

First, the use of handler

The main functions of the handler class are two:

"Sends a message in a newly-started thread

"Gets in the main thread, processes the message

In order for the main thread to "timely" handle the message sent by the newly-started thread, it can only be implemented by means of a callback.

Overrides the method that handles the message in the handler class; The message is sent to the MessageQueue associated with the newly-started thread, and handler constantly gets and processes the message from MessageQueue This causes the method in the handler class to process the message to be recalled.

 new  Thread (new   Runnable () {@Override  public  void run () { try      {Thread.Sleep ( 2000 catch   (Interruptedexception e) {E.prin    Tstacktrace ();    The Message msg  = Handler.obtainmessage (); Msg.what  = Constant.user_login;      Msg.obj  = "You have not registered yet, are you quick to login"  
New Handler () {    publicvoid  handlemessage (android.os.Message msg) {          Super. Handlemessage (msg);         if (Activity.isfinishing ()) {          return;        }         if (Msg.what = = constant.user_login) {        toastutils.showshort (activity, msg.obj.toString ());}}    ;

Ii. several components working with Handler, Looper, MessageQueue

Looper: Each thread has only one Looper, which is responsible for managing the messagqueue, and constantly takes the message out of the total MessageQueue and assigns the message to the corresponding handler processing.

"MessageQueue: Looper is responsible for the management. Use FIFO to manage message.

"Handler: Send the message to the Looper management MessageQueue, and handle the message that Looper has given it.

Third, the use of handler source analysis:

The steps for using handler in a thread are as follows.

Private class extends Thread {    public  Handler mhandler;    @Override    publicvoid  run () {    looper.prepare ();     New Handler () {        @Override        publicvoid  handlemessage (Message msg) {        log.i (TAG, msg.tostring ());        }    ;    Looper.loop ();    }}

-Call Looper's prepare () method to create a Looper object for the current thread, and when the Looper object is created, the constructor creates the MessageQueue associated with it.

 Public Final classLooper {Private Static FinalString TAG = "Looper"; //Sthreadlocal.get () would return null unless you ' ve called prepare ().     Static FinalThreadlocal<looper> sthreadlocal =NewThreadlocal<looper>(); Private StaticLooper Smainlooper;//guarded by Looper.class      FinalMessageQueue Mqueue; FinalThread Mthread; PrivatePrinter mlogging; }  
 Public Static voidPrepare () {Prepare (true); }    Private Static voidPrepareBooleanquitallowed) {          if(Sthreadlocal.get ()! =NULL) {                 Throw NewRuntimeException ("Only one Looper could be created per thread"); }          //Here's a new Looper object .Sthreadlocal.set (NewLooper (quitallowed)); }  }  

-After Looper, create an instance of the handler subclass, overriding the Handlemessage () method, which is responsible for handling messages from other threads.

//Construction Method PublicHandler () { This(NULL,false);}  PublicHandler (Callback Callback,Booleanasync) {      if(find_potential_leaks) {Finalclass<?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 ()); }} mlooper=Looper.mylooper (); if(Mlooper = =NULL) {          Throw NewRuntimeException ("Can ' t create handler inside thread that have not called looper.prepare ()"); } mqueue=Mlooper.mqueue; Mcallback=callback; Masynchronous=Async; }  

-Call Looper's Loop () method to start Looper.

 Public Static voidLoop () {FinalLooper me =Mylooper (); if(Me = =NULL) {        Throw NewRuntimeException ("No Looper; Looper.prepare () wasn ' t called on the This thread. "); }    FinalMessageQueue queue =Me.mqueue;binder.clearcallingidentity (); Final LongIdent =binder.clearcallingidentity ();  for (;;) {Message msg= Queue.next ();//Get Message Queue laugh a message that no message will block        if(msg = =NULL) {            //if the message is empty, Message Queuing is exiting            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);        } msg.target.dispatchMessage (msg); if(Logging! =NULL) {logging.println ("<<<<< finished to" + Msg.target + "" +msg.callback); }        //Use the final decorated identifier to ensure that the thread identifier is not changed during message distribution        Final LongNewident =binder.clearcallingidentity (); if(Ident! =newident) {LOG.WTF (TAG,"Thread identity changed from 0x" + long.tohexstring (Ident) + "to 0x" + Long.tohexs  Tring (newident) + "while dispatching to" + Msg.target.getClass (). GetName () + "" + Msg.callback + "what=" +msg.what);    } msg.recycle (); }}

Handler message delivery 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.