Android: Asynchronous Message source code parsing

Source: Internet
Author: User

About the use of asynchronous messages, you can see a previous article http://blog.csdn.net/leelit/article/details/45196827, now to parse the source code.

Classic usage
class LooperThread extends Thread {      public Handler mHandler;      publicvoid run() {          Looper.prepare();          new Handler() {              publicvoid handleMessage(Message msg) {                  // process incoming messages here              }          };          Looper.loop();      }  }

As a result, we can send a message to the current thread on another thread, via handler, to achieve the asynchronous effect.

Process

1. Looper.prepare();
This method calls the following methods:

 public   Static  void  prepare  () {Prepare (true ); } private  static   void  prepare  (Boolean quitallowed) {if  (ST Hreadlocal. get  ()! = null ) {throw  new  runtimeexception (" only one Looper could be created per thread "); } sthreadlocal. set     (new  Looper (quitallowed)); }

The Prepare method sets a Looper object for the Threadlocal object, and the thrown exception shows that each thread can have only one Looper object, so what is this looper for?

    privateLooper(boolean quitAllowed) {        new MessageQueue(quitAllowed);        mThread = Thread.currentThread();    }

Looper binds the current thread and MessageQueue.

2. mHandler = new Handler() {...};
Instantiate the handler object, then back to analyze the role of the handler object

3.Looper.loop();

     Public Static void Loop() {FinalLooper me = Mylooper ();if(Me = =NULL) {Throw NewRuntimeException ("No Looper; Looper.prepare () wasn ' t called on the This thread. "); }FinalMessageQueue queue = Me.mqueue;//Make sure the identity of this thread is the the local process,        //And keep track of the What, identity token actually is.Binder.clearcallingidentity ();Final LongIdent = Binder.clearcallingidentity (); for(;;) {Message msg = Queue.next ();//might block            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); } msg.target.dispatchMessage (msg);if(Logging! =NULL) {Logging.println ("<<<<< finished to"+ Msg.target +" "+ Msg.callback); }//Make sure that during the course of dispatching the            //identity of the thread wasn ' t corrupted.            Final LongNewident = 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.recycleunchecked (); }    }

2nd, 6 line can see, this method obtains the Looper object and the main MessageQueue object, the emphasis looks at 13, 14 lines, the method inside is a dead loop, continuously pulls the message from the MessageQueue inside, and is the blocking type, That means you can't pull the message and stop there. Assuming the message is pulled, the 27th line is called

msg.target.dispatchMessage(msg);

It is clear that the message is distributed to the processor. And here the Msg.target is the handler object.

    publicvoiddispatchMessage(Message msg) {        ifnull) {            handleCallback(msg);        else {            ifnull) {                if (mCallback.handleMessage(msg)) {                    return;                }            }            handleMessage(msg);        }    }

Let's take a look at each of these three possibilities, which are also common scenarios:
①handler Object post a task

        handler.post(new Runnable() {            @Override            publicvoidrun() {            }        });

Continue calling

    publicfinalbooleanpost(Runnable r) {       return  0);    }    privatestaticgetPostMessage(Runnable r) {        Message m = Message.obtain();        m.callback = r;        return m;    }

You can see that the task that the handler post goes into will be assigned to the message before the MessageQueue is queued, and this task will be called when the message handler processed.

② a callback object when instantiating a handler object

new Handler(new Handler.Callback() {            @Override            publicbooleanhandleMessage(Message msg) {                returnfalse;            }        });
ifnull) {                if (mCallback.handleMessage(msg)) {                    return;                }            }

The Handlemessage method is eventually recalled.

③ The most common scenario, when instantiated, overrides the Handlemessage (msg) method, which is also the last possibility of the above message distribution.

Last two minor questions,
1, message MessageQueue the queue operation is carried out by the handler object, the queue will be set to target the current operation of the handler, so processing the message can find the appropriate handler!
2, the main thread of the Looper is generated by the system, looking for a half-day source did not see, but the official documents are very clearThe main looper for your application is created by the Android environment

Summary

The handler object is responsible for passing the message into MessageQueue, and MessageQueue is generated by the Looper object;
The Looper object is responsible for creating the MessageQueue object and constantly fetching the message from MessageQueue, and once it is removed, it will be handler processed directly or indirectly.

Research Asynctask source code can be found, the interior is the encapsulation of handler;
It is common to implement a child thread to send a message to the main thread, and it will be clearer to try to send a message to the child thread.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Android: Asynchronous Message source code parsing

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.