Original Address:Deep understanding of the fundamentals of Android Message Processing systems
Hoarn
The Android app is also message-driven and, as a rationale, should provide a message loop mechanism. In fact, Google referenced the Windows message loop mechanism, also implemented in the Android system message loop mechanism.
Android uses Looper, handler to implement the message loop mechanism, the Android message loop is for threads (each thread can have its own message queue and message loop).
This article provides an in-depth introduction to the fundamentals of Android Message processing system.
Looper is responsible for managing the thread's message queue and message loop in the Android system, please refer to Looper's source code for specific implementation. The Looper object of the current thread can be obtained through Loop.mylooper (), and the Looper object of the current process's main thread can be obtained through Loop.getmainlooper ().
The Message Queuing and message loops mentioned in the previous Android system are for a specific thread, a thread can exist (or can not exist) a message queue and a message loop (Looper), the message of a particular thread can only be distributed to this thread, not cross-threading, cross-process communication. However, the worker threads created by default have no message loops and message queues, and if you want the thread to have Message Queuing and message loops, you need to First call Looper.prepare () in the threads to create the message queue, and then call Looper.loop () to enter the message loop. As shown in the following example:
Class Looperthread extends Thread {
Public Handler Mhandler;
public void Run () {
Looper.prepare ();
Mhandler = new Handler () {
public void Handlemessage (Message msg) {
Process incoming messages here}};
Looper.loop ();
} }
This way your thread has a message processing mechanism, and the message processing is done in handler.
Activity is a UI thread that runs in the main thread, and the Android system creates a message queue and message loop (Looper) for activity when it starts. Please refer to the Activitythread.java file for detailed implementation.
The role of handler is to add messages to a specific (Looper) message queue and to distribute and process messages in that message queue. When constructing handler, you can specify a Looper object that is created with the looper of the current thread if not specified. For detailed implementation please refer to Looper source code.
The relationship between Activity, Looper, and handler is as follows:
One activity can create multiple worker threads or other components, and if those threads or components put their messages into the activity's main thread message queue, the message will be processed in the main thread. Because the main thread is generally responsible for the interface update operation, and the Android system Weget is not thread-safe, so this way can be a good implementation of Android interface update. This approach is widely used in Android systems.
So how does another thread put the message into the message queue of the main thread?
The answer is through the handle object, as long as the handler object is created with the looper of the main thread, then invoking the SendMessage and other interfaces of the handler will put the message into the queue will be put into the main thread of the message queue. The handler's Handlemessage interface will be called in the handler main thread to process the message.
This involves thread synchronization issues, please refer to the following example to understand the threading model of the Handler object:
1, first create the MyHandler project.
2, add the following code in the Myhandler.java:
Package Com.simon;
Import android.app.Activity;
Import Android.os.Bundle;
Import Android.os.Message;
Import Android.util.Log;
Import Android.os.Handler;
public class MyHandler extends Activity {
Static final String TAG = Handler;
Handler h = new Handler () {
public void Handlemessage (Message msg) {
Switch (msg.what) {
Case HANDLER_TEST:LOG.D (TAG, the HANDLER threadn);
Break
};
static final int handler_test = 1;
@Override public void OnCreate (Bundle savedinstancestate)
{super.oncreate (savedinstancestate);
LOG.D (TAG, the main THREADN);
New MyThread (). Start ();
Setcontentview (R.layout.main);
} class MyThread extends Thread {
public void Run () {
Message msg = new Message ();
Msg.what = Handler_test;
H.sendmessage (msg);
LOG.D (TAG, the worker Threadn);
In this example we mainly print, this processing mechanism of the various modules in the thread situation. Here are the results of my machine running:
09-10 23:40:51.478:debug/handler (302): The main thread 09-10 23:40:51.569:debug/handler (302): The worker thread 09-10 23 : 40:52.128:debug/handler (302): the Handler thread>
We can see that message processing is handled in the main thread, and it is safe to call any resource in the main thread, including the refresh interface, in the message handler function. The worker thread and the main thread run in different threads, so you must be aware of the competing relationships between the two threads.
In the example above, you may have noticed that the main thread handler object was accessed in the worker thread, and a message was added to the message queue by the object that called handler. Is there a problem with the message queue data inconsistency in this process? The answer is that the handler object is not problematic because the Looper object managed by the handler object is thread-safe, whether it is to join the message to the message queue and read the message from the queue to be protected by a synchronous object. Please refer to the Looper.java file for details. The handler object is not modified in the previous example, so there is no possibility that the handler object will have data inconsistencies.
From the above analysis, we can draw the following conclusions:
1. If you refresh the interface through a worker thread, it is recommended to use the handler object.
2. Pay attention to the competitive relationship between the worker thread and the main thread. It is recommended that the handler object be constructed in the main thread (and do not modify it after starting the worker thread, otherwise there will be inconsistent data), and then the interface can be safely invoked in the worker thread to send the message SendMessage.
3. If the member variable of any main thread other than the Hanlder object described in 2 is called in a worker thread, carefully consider thread synchronization issues. If necessary, add a synchronization object to protect the variable.
4. The Handlemessage interface of the handler object will be called in the main thread. In this function, you can safely invoke any variables and functions in the main thread to complete the task of updating the UI.
5. Many Android APIs also use handler as a variant of a callback function to inform the caller of this threading feature. This allows the Android framework to send messages to the caller's thread message queue in its thread without worrying about thread synchronization.
An in-depth understanding of the Android message processing mechanism is important for application development and allows you to gain a deeper understanding of thread synchronization.
[Go] in-depth understanding of how Android messaging systems work