Android Note (33) communication between Android Threads (v) Handle, Looper, and MessageQueue

Source: Internet
Author: User

ThreadLocal

Before looking down, you need to know about Java's threadlocal class, you can refer to the blog:

Decryption Threadlocal

Looper, Handler and MessageQueue

Let's analyze the previous code and see what the relationship between Handle, Looper, and MessageQueue is in the handler mechanism.

classWorkerthreadextendsThread {@Override Public voidrun () {Super. Run ();            Looper.prepare (); Handler=NewHandler () {@Override Public voidhandlemessage (Message msg) {Super. Handlemessage (msg); LOG.D ("Tttt", "Handlemessage:" +Thread.CurrentThread (). GetName ()); inti =Msg.what; LOG.D ("Tttt", "Received Message object:" +i);            }            };        Looper.loop (); }    }

1. First implement Looper.prepare () ;

To view the source code for Looper, the path is: Sources\android-19\android\os\looper.java

First, several member variables of the Looper class

    // Sthreadlocal.get () would return null unless you ' ve called prepare ().    Static Final New Threadlocal<looper>();     Private Static Looper Smainlooper;  // guarded by Looper.class    Final MessageQueue mqueue;     Final Thread Mthread;

This indicates that each Looper object corresponds to a message queue (MessageQueue), and also to a thread.

When we call Looper's prepare () method, execute the following code:

 public  static  void   prepare () {Prepare ( true  Span style= "color: #000000;" >);} private  static  void  Prepare (boolean   quitallowed) { if  (sthreadlocal.get ()! = null       New  runtimeexception ("Only one Looper could be created per thread"  new   Looper ( quitallowed));}  

As can be seen from the code above, when Looper.prepare () is executed, the threadlocal get method is called to determine if there is already a key-value pair with the current thread as key, and if it already exists, throws an exception "only one Looper may Be created per thread " . If it does not exist, execute sthreadlocal.set (new Looper (quitallowed)) , create a new Looper object, and deposit it in threadlocal.

Private Looper (boolean  quitallowed) {    new  MessageQueue (quitallowed);     = thread.currentthread ();}

As you can see, creating a Looper object creates a new MessageQueue object, assigns the Mqueue property to the Looper object, assigns the current thread to Looper's Mthread property.

2. Next execution

    New Handler () {                @Override                publicvoid  handlemessage (Message msg) {                      Super. Handlemessage (msg);                    LOG.D ("tttt", "Handlemessage:" + Thread.CurrentThread (). GetName ());                     int i = msg.what;                    LOG.D ("Tttt", "Received Message object:" + i);}            };

Instantiate a handler object, execute its Handlemessage method, view handler source, path: Sources\android-19\android\os\hnadler.java

You can see that the handler class has the following member variables

    Final MessageQueue mqueue;     Final Looper mlooper;     Final Callback mcallback;     Final Boolean masynchronous;    IMessenger Mmessenger;

Find the construction method of its handler

     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; }

The Looper mylooper () method is called to assign a value to Mlooper

    Mlooper = Looper.mylooper ();

We view Looper.java

     Public Static Looper Mylooper () {        return  sthreadlocal.get ();    }

found that the Looper object that is the key of the current thread is removed from the threadlocal and returned, so when the handler object is created, the handler object gets the Looper object that was created before

if NULL  ) {  thrownew  runtimeexception (                "Can ' t create handler inside thread that have not  Called Looper.prepare () "); }

If the Looper object is empty, throw an exception "Can ' t create handler inside thread that have not called looper.prepare ()" informs the user that there is no call to Looper. You cannot create a handler object before Preapre ().

    Mqueue = mlooper.mqueue;     = callback;     = Async;

The mqueue of the Looper object is then given to the mqueue of handler.

In this way, the thread, Handler, Looper, MessageQueue are linked together.

  

Android Note (33) communication between Android Threads (v) Handle, Looper, and MessageQueue

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.