Android's message processing has three core classes: Looper,handler and message. There's actually a message queue, but MQ is encapsulated in Looper, and we don't deal directly with MQ, so I don't use it as a core class. Here are the following:
Thread of the magician Looper
Looper literally means "circulator", which is designed to make a normal thread into a looper thread . The so-called Looper thread is the thread that loops work. In program development (especially in GUI development), we often need a thread to loop continuously, and once a new task is executed, the execution continues to wait for the next task, which is the looper thread. Creating a Looper thread with the Looper class is simple:
public class Looperthread extends Thread {
@Override
public void Run () {
Initializes the current thread to a looper thread
Looper.prepare ();
// ... Other processing, such as instantiation of handler
Start loop processing of Message Queuing
Looper.loop ();
}
}
public class Looperthread extends Thread {
@Override
public void Run () {
Initializes the current thread to a looper thread
Looper.prepare ();
// ... Other processing, such as instantiation of handler
Start loop processing of Message Queuing
Looper.loop ();
}
}
With the above two lines of core code, your thread will be upgraded to Looper thread!!! Isn't it amazing? Let's slow down and see what each of these two lines of code does.
1) Looper.prepare ()
As you can see, you now have a Looper object in your thread that internally maintains a message queue MQ. Note that a thread can have only one Looper object.
2) Looper.loop ()
When the loop method is called, the Looper thread begins to actually work, and it continuously executes the message (also called the task) that pulls the team header from its own MQ.
In addition to the prepare () and loop () methods, the Looper class provides some useful methods, such as
Looper.mylooper () Gets the current thread Looper object:
public static final Looper Mylooper () {
Calling Looper.mylooper () on any thread will return the looper of that thread.
Return (Looper) sthreadlocal.get ();
}
public static final Looper Mylooper () {
Calling Looper.mylooper () on any thread will return the looper of that thread.
Return (Looper) sthreadlocal.get ();
}
GetThread () Gets the thread that the Looper object belongs to:
Public Thread GetThread () {
return mthread;
}
Public Thread GetThread () {
return mthread;
}
The Quit () method ends the Looper loop:
public void Quit () {
Creates an empty message whose target is null, which indicates the end of the loop message
Message msg = Message.obtain ();
Send a message
Mqueue.enqueuemessage (msg, 0);
}
So far, you should have a basic understanding of looper and summarize some of the points:
1. Each thread has and can have at most one Looper object, which is a threadlocal
2.Looper has a message queue inside, the loop () method call after the thread begins to continuously remove the message from the queue execution
3.Looper causes a thread to become a looper thread.
So how do we add a message to MQ? Here's handler!. (Applause ~ ~ ~)
Asynchronous Processing Master Handler
What is handler? Handler plays the role of adding messages and processing messages to MQ (handling only messages sent by itself), notifying MQ that it is going to perform a task (sendMessage) and performing the task (Handlemessage) at loop to its own. The entire process is asynchronous . Handler is created with a looper associated with it, the default constructor associates the looper of the current thread, but this can be set. The default construction method:
Here we can add handler to the previous Looperthread class:
public class Looperthread extends Thread {
Private Handler handler1;
Private Handler Handler2;
@Override
public void Run () {
Initializes the current thread to a looper thread
Looper.prepare ();
Instantiation of two Handler
Handler1 = new Handler ();
Handler2 = new Handler ();
Start loop processing of Message Queuing
Looper.loop ();
}
}
public class Looperthread extends Thread {
Private Handler handler1;
Private Handler Handler2;
@Override
public void Run () {
Initializes the current thread to a looper thread
Looper.prepare ();
Instantiation of two Handler
Handler1 = new Handler ();
Handler2 = new Handler ();
Start loop processing of Message Queuing
Looper.loop ();
}
}
After adding handler, the effect is as follows:
As you can see, a thread can have multiple handler, but only one looper!
Handler sending messages
With handler, we can use,,, post(Runnable)
, postAtTime(Runnable, long)
postDelayed(Runnable, long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message, long)
and sendMessageDelayed(Message, long)
These methods to send messages to MQ. Look at these APIs you may feel that handler can send two kinds of messages, one is Runnable object, one is a message object, this is a visual understanding, but in fact, the post runnable object is encapsulated into a message object, see source code:
Other methods are not listed, in short, through the handler issued by the message has the following characteristics:
1.message.target is the handler object, which ensures that the key code in the loop () method can be found when Looper executes to the message, which is the handler that handles it
Msg.target.dispatchMessage (msg);
Message sent by 2.post with callback as Runnable object
Handler processing messages
After the message is sent, see how handler handles the message. The processing of messages is done through the core method DispatchMessage (Message msg) with the Hook method handlemessage (Message msg)
As you can see, except for the Handlemessage (Message msg) and Runnable objects, the Run method is implemented by the developer (implementing specific logic), and the internal working mechanism of handler is transparent to the developer. That's what makes the handler API design so subtle!
The usefulness of handler
I described handler as "the Master of Asynchronous processing" in a small title, thanks to Handler's two key features:
1.handler can send messages on any thread that is added to the associated MQ.
2.handler is the processing of messages in its associated looper thread .
This solves the problem of Android's classic inability to update the UI in other non-main threads. the main thread of Android is also a looper threading (Looper is widely used in Android), the handler we create in it will be associated with the main thread MQ by default. Thus, one solution of handler is to create handler in the activity and pass its reference to the worker Thread,worker thread to send a message to notify the activity update UI after performing the task. Process
Encapsulate Task Message
In the entire message processing mechanism, message is called a task, encapsulating the information carried by the task and the handler that handles the task. The use of the message is relatively simple and is not summed up here. But there are a few points to note (to add):
1. Although the message has a public default constructor, you should use Message.obtain () to obtain an empty message object from the message pool to conserve resources.
2. If your message only needs to carry simple int information, prioritize using MESSAGE.ARG1 and message.arg2 to pass information, which is more memory-saving than using bundles
3. Use Message.what to identify information so that you can handle the message in different ways.
Reprinted from Http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html
Android message processing mechanism (figure + source analysis)--looper,handler,message