Handler is primarily the main thread and sub-threading communication. In general, some time-consuming operations in a child thread are done to notify the main thread to modify the UI.
In fact, the Android system in activity startup or state changes are implemented through the handler mechanism.
First, enter into the main method of Activitythread
public static void Main (string[] args) { ... Looper.preparemainlooper (); Activitythread thread = new Activitythread (); Thread.attach (false); if (Smainthreadhandler = = null) { Smainthreadhandler = Thread.gethandler (); } ... Looper.loop (); ...}
The following is the main analysis of the above sentence code.
1. looper.preparemainlooper ();
public static void Preparemainlooper () { prepare (false); Synchronized (looper.class) { if (smainlooper! = null) { throw new IllegalStateException ("The main Looper has Alre Ady been prepared. "); Smainlooper = Mylooper (); }} private static void Prepare (Boolean quitallowed) { if (sthreadlocal.get () = null) { throw new RuntimeException (" Only one Looper could be created per thread "); Sthreadlocal.set (New Looper (quitallowed));//Create a new Looper object for this thread }
The Looper constructor is as follows
Private Looper (Boolean quitallowed) { mqueue = new MessageQueue (quitallowed);//looper maintains a message queue Mrun = true;< C15/>mthread = Thread.CurrentThread ();}
Summary: After Loop.prepare is called, a message pump looper is created for the current thread, and this looper maintains a message queue MessageQueue
2. Smainthreadhandler =thread.gethandler ();
Smainthreadhandler is the handler object, the GetHandler method is as follows:
Final Handler GetHandler () { return mH; }
See MH defined in front as final h MH = new H (); actually h is inherited from handler. Some of the code is as follows:
Private class H extends Handler {public static final int launch_activity = +; public static final int pause_activity = 101; ... public void Handlemessage (Message msg) { if (debug_messages) slog.v (TAG, ">>> handling:" + codetostring (M Sg.what)); Switch (msg.what) {case launch_activity: { trace.tracebegin (Trace.trace_tag_activity_manager, " Activitystart "); Activityclientrecord r = (activityclientrecord) msg.obj; R.packageinfo = Getpackageinfonocheck ( r.activityinfo.applicationinfo, r.compatinfo); Handlelaunchactivity (R, NULL); Trace.traceend (Trace.trace_tag_activity_manager); } break; ......} ......}
Summary: This is equivalent to creating a handler in the UI thread to implement his Handlermessage method.
3.looper.loop ();
public static void Loop () { ... Final MessageQueue queue = Me.mqueue; for (;;) { Message msg = Queue.next ();//might block if (msg = = null) { return; } ... Msg.target.dispatchMessage (msg); Msg.recycle (); }}
Summary: Call Looper.loop (), you can see the for loop, keep fetching messages from the message queue, and then distribute the Msg.target.dispatchMessage (msg); The msg.target here is the handler object, which refers to the handler that handles the message.
public void DispatchMessage (Message msg) { if (msg.callback! = null) { handlecallback (msg); } else { if ( Mcallback! = null) { if (Mcallback.handlemessage (msg)) { return; } } Handlemessage (msg); } }
Call DispatchMessage, if the message set a callback function to execute the callback, or if the definition of handler when the callback function to execute the incoming callback, otherwise the Handlermessage function will be executed, you can see that there is a priority order. When the system is processed, Handlermessage is executed because the callback is not set.
For example, when the launch_activity message is received, it executes handlelaunchactivity----performlaunchactivity----minstrumentation.newactivity (cl , Component.getclassname (), r.intent); -----minstrumentation.callactivityoncreate (activity,r.state); -----activity.performcreate (Icicle);
This carries out the OnCreate method of the entrance of our usual so-called activity.
By now we have seen the application of the handler mechanism in Android. Next, analyze how handler and Looper are linked together.
The handler constructor will eventually be executed.
Public Handler (Callback Callback, Boolean async) { if (find_potential_leaks) { final class<? extends handler& Gt 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 ();//Gets the current thread's Looper if (mlooper = = null) { throw new RuntimeException ( "Can ' t Create handler inside thread that have not called looper.prepare () "); } Mqueue = mlooper.mqueue;//passes the message queue of the Looper object to the members of the handler, allowing handler to manipulate the message loop Mcallback = callback; masynchronous = async;}
The message class is as follows
Public final class Message implements parcelable {public int-what ; public int arg1; public int arg2; ... Handler Target; Each message has a member save and his associated handler Runnable callback; }
Now let's take a look at what happens when I call handler's SendMessage message.
Public Final Boolean sendMessage (Message msg) { return sendmessagedelayed (msg, 0); }
The final execution is:
Private Boolean enqueuemessage (MessageQueue queue, Message msg, long Uptimemillis) { Msg.target = this;// Here the this is copied to the handler member of the message, this is the handler object that we define. if (masynchronous) { msg.setasynchronous (true); } Return Queue.enqueuemessage (msg, uptimemillis);//Then add to Message queue }
msg.target = this; So there is msg.target.dispatchMessage (msg) in the loop message looping function, to distribute the message. Because more than one will execute our implementation of the code inside the Handlermessage.
Handler principle in Android