Detailed explanation of Android message mechanism and example code

Android message mechanism

1. General

When the Android application starts, there will be a main thread (UI thread) by default. A message queue will be associated with this thread. All operations will be encapsulated into a message queue and then handed over to the main thread for processing. In order to ensure that the main thread will not exit, the operation of the message queue will be placed in an endless loop. The program is equivalent to always executing an endless loop. Once in the loop, take a message from its internal message queue, and then call back the corresponding message processing function (handlermessage). After executing a message, continue the loop. If the message queue is empty, Threads block waiting. Therefore, it will not exit. As shown in the figure below:

What is the relationship between handler, looper and message?

To complete time-consuming operations in the sub thread, the UI needs to be updated in many cases. The most common method is to post a message to the UI thread through the handler, and then process it in the handler's handlermessage method. Each handler will be associated with a message queue. Looper is responsible for creating a message queue, and each looper will be associated with a thread (looper is encapsulated by ThreadLocal). By default, there is only one messagequeue, that is, the message queue of the main thread.

The above is the basic principle of Android message mechanism. If you want to know more, let's start with the source code.

2. Source code interpretation

(1) Start message loop looper in activitythread main thread

Activitythread creates the message queue of the main thread through loop. Preparemainloop(), and finally executes loop. Loop() to start the message queue. Handler associates message queues and threads.

(2) Handler associates message queues and threads

The handler will get the looper object internally through the looper. Getlooper () method, associate with it, and get the message queue. So how does looper. Getlooper () work?

In the Looper class, the myLooper () method, obtained by sThreadLocal.get (), calls the prepare () method in prepareMainLooper (), creates a Looper object in this method, and sets sThreadLocal () for the object. The queue is then associated with the thread. Ensure that different threads cannot access each other's message queue through the sthreadlocal. Get() method.

Why must the handler for updating the UI be created in the main thread?

Because the handler needs to be associated with the message queue of the main thread, the handler message will be executed in the UI thread, and the UI thread is safe at this time.

(3) Message loop

The message loop is established through the loop. Loop () method. The source code is as follows:

From the above procedure, we can see that the essence of loop () method is to establish an endless loop, then take out the messages one by one from the message queue, and finally process the messages. For looper: create a looper object through looper. Prepare() (the message queue is encapsulated in the looper object) and save it in sthreadlocal, and then loop the message through looper. Loop(). These two steps usually occur in pairs.

As can be seen from the source code, target is of type handler. In fact, it turns around and sends messages to the message queue through the handler, and the message queue distributes the messages to the handler for processing. In the handle class:

As can be seen from the above procedures, dispatchmessage is only a distribution method. If the callback of run nable type is empty, execute handlemessage to process the message. If the method is empty, we will write the code to update the UI in this function; If the callback is not empty, execute handlecallback to handle it, and this method will call the run method of the callback. In fact, these are two types of handler distribution. For example, if post (runnable callback) is used, the callback is not empty. When we use handler to send message, we usually do not set callback. Therefore, execute handlermessage.

As can be seen from the above procedures, when posting (runnable R), the runnable will be wrapped into a message object, and the runnable object will be set to the callback of the message object. Finally, the object will be inserted into the message queue. SendMessage is also a similar implementation:

Whether a runnable or a message is posted, the sendmessagedelayed (MSG, time) method will be called. The handler finally adds messages to the messagequeue, and looper constantly reads messages from the messagequeue and calls the dispatcher message of the handler to distribute messages. In this way, messages are continuously generated, added to the messagequeue and processed by the handler, and the Android application runs.

3. Inspection

Is there a problem with the above code?

The looper object is ThreadLocal, that is, each thread uses its own looper, which can be empty. However, when a handler object is created in a child thread, an exception occurs if looper is empty.

An exception is thrown when mloop is empty. This is because the looper object was not created, so sthreadlocal. Get() will return null. The basic principle of the handler is to establish an association with the messagequeue and deliver the message to the messagequeue. If there is no messagequeue, there is no need for the handler to exist, and the messagequeue is sealed in the looper. Therefore, when creating the handler, the looper must not be empty. The solution is as follows:

If only the looper is created and the message loop is not started, although no exception is thrown, post or SendMessage () through the handler will not be effective. Because although the message will be added to the message queue, the message loop is not started, so the message will not be obtained from the message queue and executed.

Thank you for reading, hope to help you, thank you for your support to this site!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>