In depth understanding of Android message circulation mechanism source code

Android message loop mechanism source code

preface:

Android users who don't understand the handler message loop mechanism are embarrassed to say they are Android engineers. This knowledge point is usually asked during the interview, but I believe most digital farmers have never seen the relevant source code. At most, they search online and see other people's articles. The elder sister doesn't want to discuss the omnipotent relationship diagram.

Recently, I found some information about the communication between Android threads, sorted and studied it, and made a simple example.

Android provides handler and looper to meet the communication between threads. For example, when a child thread downloads a picture from the network, it will send a message to the main thread. This message is passed through the handler bound to the main thread.

In Android, threads here are divided into threads with message loops and threads without message loops. Threads with message loops generally have a looper, which is a new concept of Android. Our main thread (UI thread) is a thread of message loop. For this message loop mechanism, we introduce a new mechanism handle. If we have a message loop, we need to send corresponding messages to the message loop. Custom messages generally have their own corresponding processing, message sending and clearing, and message processing. These are encapsulated in the handle. Note that the handle is only for those threads with loopers, Whether it is UI thread or sub thread, as long as you have looper, I can add something to your message queue and handle it accordingly. However, there is another point here, that is, as long as it is related to the UI, it cannot be placed in the sub thread, because the sub thread cannot operate the UI, and can only operate data, system and other non UI operations.

In Android, threads here are divided into threads with message loops and threads without message loops. Threads with message loops generally have a looper, which is a new concept of Android. Our main thread (UI thread) is a thread of message loop. For this message loop mechanism, we introduce a new mechanism handler. If we have a message loop, we need to send corresponding messages to the message loop. Custom messages generally have their own corresponding processing, message sending and clearing. These are encapsulated in the handler. Note that the handler is only for those threads with loopers, Whether it is UI thread or sub thread, as long as you have looper, I can add something to your message queue and handle it accordingly.

However, there is another point here, that is, as long as it is related to the UI, it cannot be placed in the sub thread, because the sub thread cannot operate the UI, and can only operate data, system and other non UI operations.

This mechanism is first derived from our usual use methods, and then analyzed in combination with the source code.

We usually use this:

So why do we execute 1 or 2 during initialization and then only need SendMessage to process the task? Sister, take the non main thread as an example. When handlerthread. Start(), it actually creates a looper and message queue for message loop. At the same time, it starts the message loop and passes it to the handler. This loop will take tasks from the message queue in turn for execution. To perform a task, users only need to call handler.sendmessage. What they do here is to add the message to messaequeue. The same is true for the main thread, except that the main threads smainthread and smainlooper do not need to be created on our own initiative. The application is created when the program starts, and we only need to create a handler.

We mentioned several concepts here:

The correspondence is: one to many, i.e. (one) handlerthread, looper, messagequeue - > (multiple) handler and message

Source code analysis

1. Looper

(1) Create message loop

Prepare() is used to create a looper message loop object. The looper object is saved through a member variable ThreadLocal.

(2) Get message loop object

Myloop() is used to get the current message loop object. The looper object is obtained from the member variable ThreadLocal.

(3) Start message loop

Loop () starts the message loop. The cycle process is as follows:

One message is fetched from the message queue at a time

Use the handler corresponding to the message to process the message

The processed messages are added to the local message pool for cyclic reuse

Cycle the above steps. If there is no message indicating that the message queue stops, exit the cycle

2. Handler

(1) Send message

Handler supports two message types, runnable and message. Therefore, post (runnable R) and SendMessage (message MSG) are provided for sending messages. From the following source code, we can see that runnable assigns a value to the callback of message, which is finally encapsulated into a message object. The student sister personally believes that external calls do not use message uniformly and should be Java compatible thread tasks. The student sister believes that this idea can also be used for reference in the ordinary development process. All messages sent will be queued to the messagequeue.

(2) Processing messages

During looper loop process, messages are processed through dispatchmessage (message MSG). Processing process: first check whether it is a runnable object. If so, call handlecallback (MSG) for processing, and finally call the runnable. Run () method to execute the thread; If it is not a runnable object, check whether the external callback processing mechanism is passed in. If so, use the external callback for processing; If it is neither a runnable object nor an external callback, call handlemessage (MSG), which is also the most frequently overridden method in our development process.

(3) Remove message

Removecallbacksandmessages(). To remove a message is actually to remove the message object from the messagequeue.

3. MessageQueue

(1) Message queue

Message queuing method enqueuemessage (message MSG, long when). The treatment process is as follows:

The message to be queued is marked as inuse and assigned when

If the message chain list mmessages is empty, or the execution time of the messages to be queued is less than the mmessage chain header, the messages to be queued will be added to the chain header

If the above conditions are not met, poll the linked list and insert the appropriate position of the linked list according to the order of when from low to high

(2) Message polling

Next() takes out messages from the messagequeue in turn

(3) Remove message

Removemessages () can remove messages. What it does is actually remove messages from the linked list, and add the removed messages to the message pool to provide circular reuse.

4. Message

(1) Message creation

Message. Obtain() creates a message. If the message pool chain table spool is not empty, get the first one from spool, mark flags as uninuse, and remove it from spool at the same time, spoolsize minus 1; If the message pool chain table spool is empty, new message()

(2) Message release

Recycle() releases the message. From the internal implementation of recycleunchecked(), it can be seen that flags are marked as inuse, other states are cleared, messages are added to spool, and spoolsize is increased by 1

5. HandlerThread

Because the thread in Java has no message loop mechanism, the run () method is executed and the thread ends. Handlerthread implements the message loop by using looper. As long as you don't actively call the quit () method of handlerthread or looper, the loop will go on.

summary

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
分享
二维码
< <上一篇
下一篇>>