We used to use the SendMessage () method to send a message, using Handlemessage to process the message, today we look at the other way, first look at the code:
Packagecn.lixyz.handlertest;Importandroid.app.Activity;ImportAndroid.os.Bundle;ImportAndroid.os.Handler;ImportAndroid.util.Log;ImportAndroid.view.View;ImportAndroid.widget.Button;ImportAndroid.widget.TextView; Public classMainactivityextendsActivity {Privatebutton button; PrivateHandler Handler =NewHandler (); PrivateTextView TextView; @Overrideprotected voidonCreate (Bundle savedinstancestate) {Super. OnCreate (savedinstancestate); Setcontentview (R.layout.activity_main); TextView=(TextView) Findviewbyid (R.id.textview); Button=(Button) Findviewbyid (R.id.button); Button.setonclicklistener (NewView.onclicklistener () {@Override Public voidOnClick (View v) {Testthread T=NewTestthread (); T.start (); } }); } classTestthreadextendsThread {@Override Public voidrun () {Super. Run (); Runnable R=NewRunnable () {@Override Public voidrun () { for(inti = 0; I < 5; i++) {LOG.D ("Tttt", (i + 1) + "seconds"); Try{Thread.Sleep (1000 * 1); Textview.settext ("Content modified after 5 seconds"); } Catch(interruptedexception e) {e.printstacktrace (); } } } }; Handler.post (R); } }}
Mainactivity.java
<LinearLayoutxmlns:android= "Http://schemas.android.com/apk/res/android"Xmlns:tools= "Http://schemas.android.com/tools"Android:layout_width= "Match_parent"Android:layout_height= "Match_parent"android:orientation= "vertical"Tools:context=". Mainactivity "> <TextViewAndroid:id= "@+id/textview"Android:layout_width= "Match_parent"Android:layout_height= "Wrap_content"Android:layout_margintop= "20DP"android:gravity= "Center"Android:text= "Before Change"android:textsize= "30SP" /> <ButtonAndroid:id= "@+id/button"Android:layout_width= "Wrap_content"Android:layout_height= "Wrap_content"android:layout_gravity= "Center"Android:layout_margintop= "30DP"Android:text= "Send Message" /></LinearLayout>
Acitivit_main.xml
Click the button to run the result:
From the code we can see that I created a new thread, a Runnable object in the thread, a Runnable object that modifies the UI, and then uses the post () method that called handler, so let's take a look at this How the Post () is implemented.
View the source code for the handler and find the post () method
Public Final Boolean Post (Runnable R) { return sendmessagedelayed (Getpostmessage (R), 0); }
We found that, in fact, the Post method directly calls a delay to send a message method sendmessagedelayed () , but the delay is 0, continue to find the getpostmessage () method
Private Static Message Getpostmessage (Runnable r) { = message.obtain (); = R; return m; }
in the code above, we found that a new Message object is acquired within the Getpostmessage method, and the Runnage object that we passed in is assigned the value of the message to the object's callback property, which is then returned
So the essence of the post () method is to assign a Runnable object to the callback property of a message property, and then put this message object into the queue of messages
And as we said before, Looper's Loop () method loops out messages from the message queue, so how does looper work at this time, find the Looper loop () method
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; //Make sure the identity of the the the 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//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" + Lon G.tohexstring (newident) + "while dispatching to" + Msg.target.getClass (). GetName () + "" + Msg.callback + "what=" +msg.what); } msg.recycle (); } }
As previously said, after the loop () method executes, the same first gets the Looper object, then begins to loop the message out of the message queue and executes to msg.target.dispatchMessage (msg); The target property is of type Handler , and we go to see the despatchmessage method of Handler
Public void DispatchMessage (Message msg) { ifnull) { handlecallback (msg); Else { ifnull) { if (Mcallback.handlemessage ( msg) { return; } } Handlemessage (msg); } }
Visible, advanced on the callback property of the received message object to judge, if not NULL, to call the Handlecallback method, view the handlecallback method
Private Static void handlecallback (Message message) { message.callback.run (); }
Message.callback.run (); Instead of creating a new thread, call the run () method of the Runnable object directly, and then call the Start method of the thread.
Android Note (34) communication between Android threads (vi) The post () method in handle