Handler is primarily the main thread and sub-threading communication. General sub-threads do some time-consuming operations after you have finished notifying the main thread to change 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 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 }
Looper constructors such as the following
Private Looper (Boolean quitallowed) { mqueue = new MessageQueue (quitallowed);//looper maintains a message queue Mrun = true;< C17/>mthread = Thread.CurrentThread ();}
Summary: After the call is finished loop.prepare. 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. GetHandler methods such as the following:
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 (). Be able to see the for loop. Continuously fetching messages from the message queue. Then distribute 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. Suppose the message has a callback function set to run the callback, otherwise assume that the definition handler when the callback function is passed into the callback, or run the Handlermessage function, you can see that there is a priority order. When the system is processed, Handlermessage is run because the callback is not set.
For example, when a launch_activity message is received, it runs handlelaunchactivity----performlaunchactivity----minstrumentation.newactivity (cl , Component.getclassname (), r.intent); -----minstrumentation.callactivityoncreate (activity,r.state); -----activity.performcreate (Icicle);
This runs to the OnCreate method of our usual so-called activity entry.
By now we have seen the application of the handler mechanism in Android.
Next, analyze how handler and Looper are linked together.
Handler's constructor is finally going to run.
Public Handler (Callback Callback, Boolean async) { if (find_potential_leaks) { final class<?Extends handler> 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 so that handler can manipulate the message loop Mcallback = callback; masynchronous = async;}
The message class such as the following
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 end will run to:
Private Boolean enqueuemessage (MessageQueue queue, Message msg, long Uptimemillis) { Msg.target = this;// Here you copy this 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 join in 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 run our implementation of the code inside the Handlermessage.
Handler principle in Android