Analysis on Android Handle Mechanism
I. Handle use cases:
1. Create a handle instance
new handle();
2. Message)
sendMessage(msg);
3. process messages
HandleMessage (Message msg ){};
Ii. Principle Analysis
Based on the handle call trilogy above, we will clarify the logic and relationship of Handle, logoff, Message, and MessageQueue.
1. new Handle (): this operation generates a Handle instance. The handle instance has three attributes: mLooper, mQueue, and mCallback. The following describes the origins of these three attributes.
1.:
MLooper = logoff. myLooper (); logoff myLooper static method is also very simple, public static logoff myLooper () {return sThreadLocal. get ();}
SThreadLocal is a singleton object, whose type is ThreadLocal This class has the set () and get () methods. The function of this class is the object of the current thread, so the function of this Code is obviously to return the logoff object of the current thread. Let's go deeper and find out where is his set method? The answer is in prepare:
private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed));}
From this method, we can see that each thread can only call the prepare method once, that is, each thread has only one loose object.
1. B:
mQueue = mLooper.mQueue;
The mQueue of the Looer object is a non-static variable, namely:
final MessageQueue mQueue;
It is also generated when the logoff is created. MessageQueue is understood as a message Queue for the time being, but it is not equivalent to: Queue.
1. c: mCallback is a callback interface with only one handleMessage method:
public interface Callback {public boolean handleMessage(Message msg);}
2. sendMessage (msg ):
This operation is the hub of the connection between them. Let's look at it one by one. First, the msg is generated, and then the message sending action.
2. a: msg generation. In the Message class, we can see a Handle type target. All msg sent to the Handle will set this target to the current Handle, such as sendMessage () the method eventually has the following operation:
msg.target = this;
2. B: sendMessage (); the queue. enqueueMessage (msg, uptimeMillis) is finally called no matter the overload method; this method will queue according to the when parameter. That is, sort in the message queue in 1. B.
3. handleMessage. a We know that logoff is a singleton of the current thread, that is, all messages of the current thread will be processed again. An endless Loop in the Loop method will traverse the Message in the mQueue and execute the dispatchMessage (msg) method:
Msg.tar get. dispatchMessage (msg );
The target of msg processes itself.
The method returns to the dispatchMessage method of the Handle class again.
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); }}
If mCallback is not empty, execute the handleMessage method of mCallback. Otherwise, execute the handleMessage method.
4. conclusion: Android uses such a clever structure to implement inter-thread communication. If you want to thoroughly understand it, take Activity as an example. In Activity, finding mainThread is the main thread we usually call, you can clearly see how logoff is created and how to manage messages.