Handler principles in Android
Handler is mainly used to communicate with sub-threads. Generally, the main thread is notified to modify the UI after some time-consuming operations are completed in the Child thread.
In fact, the android system is implemented through the Handler Mechanism during Activity startup or status change.
First, go to 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 mainly analyzes the above Code.
1. logoff. preparemainlogoff ();
Public static void prepareMainLooper () {prepare (false); synchronized (Looper. class) {if (smainloed! = Null) {throw new IllegalStateException ("The main logoff has already been prepared. ") ;}smainlooper = myLooper () ;}} private static void prepare (boolean quitAllowed) {if (sThreadLocal. get ()! = Null) {throw new RuntimeException ("Only one logoff may be created per thread");} sThreadLocal. set (new LOD (quitAllowed); // a new Looper object will be created for this thread}
The logoff constructor is as follows:
Private loue (boolean quitAllowed) {mQueue = new MessageQueue (quitAllowed); // loue maintains a Message Queue mRun = true; mThread = Thread. currentThread ();}
Summary: After Loop. prepare is called, a message pump logoff will be created for the current thread, which maintains a Message Queue MessageQueue.
2. sMainThreadHandler = thread. getHandler ();
SMainThreadHandler is a Handler object. The getHandler method is as follows:
final Handler getHandler() { return mH; }
We can see that mH is defined as final H mH = new H (); H actually inherits from Handler. Some code is as follows:
private class H extends Handler { public static final int LAUNCH_ACTIVITY = 100; public static final int PAUSE_ACTIVITY = 101; ……public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.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 its handlerMessage method.
3. logoff. 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(); }}
Conclusion: When looper.loop((, you can see the forcycle and get the Message from the queue without stopping. Then, msg.tar get. dispatchMessage (msg) is sent separately. Here msg.tar get is the Handler object, which refers to the Handler that processes 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 is set to the callback function, the callback is executed. Otherwise, if the Handler is defined, the callback is executed if the callback function is passed in. Otherwise, the handlerMessage function is executed, we can see that there is a priority order. HandlerMessage is executed because no callback is set during system processing.
For example, if you receive the LAUNCH_ACTIVITY message, handleLaunchActivity ---- Xiaoming mlaunchactivity ---- mInstrumentation will be executed. newActivity (cl, component. getClassName (), r. intent); ----- mInstrumentation. callActivityOnCreate (activity, r. state); ----- activity. using mcreate (icicle );
In this way, the onCreate method of the so-called Activity entry is executed.
Now we have seen the application of the Handler mechanism in android. Next, we will analyze how handler and logoff are associated.
The Handler constructor will eventually execute
Public Handler (Callback callback, boolean async) {if (FIND_POTENTIAL_LEAKS) {final Class
Klass = getClass (); if (klass. isAnonymousClass () | klass. isMemberClass () | klass. isLocalClass () & (klass. getModifiers () & Modifier. STATIC) = 0) {Log. w (TAG, "The following Handler class shocould be static or leaks might occur:" + klass. getCanonicalName () ;}} mLooper = Looper. myloled (); // obtain the Looper if (mloif = null) of the current thread {throw new RuntimeException ("Can't create handler inside thread that has not called loled. prepare () ");} mQueue = mloue. mQueue; // send the message queue of The logoff object to the Handler member so that the Handler can operate on 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 who saves the Handler Runnable callback associated with it ;}
Next, let's take a look at what happened when the handler sendMessage was called to send messages.
public final boolean sendMessage(Message msg) { return sendMessageDelayed(msg, 0); }
Finally, the following code is executed:
Private boolean enqueueMessage (MessageQueue queue, Message msg, long uptimeMillis) {msg.tar get = this; // copy this to the Handler Member of the Message, this is the handler object we define. If (mAsynchronous) {msg. setAsynchronous (true);} return queue. enqueueMessage (msg, uptimeMillis); // then add it to the Message queue}
Msg.tar get = this;the message is sent by msg.tar get. dispatchMessage (msg) in the loopmessage loop. Since multiple nodes will execute the code in the handlerMessage we implemented.