Working principle analysis of Android handler

brief introduction

In Android, only the main thread can operate the UI, but the main thread cannot perform time-consuming operations, otherwise it will block the thread and generate anr exceptions. Therefore, time-consuming operations are often placed in other sub threads. If the UI needs to be updated in the child thread, the message is generally sent through the handler, and the main thread accepts the message and performs corresponding logical processing. In addition to using the handler directly, you can also update the UI through the post method of view and the runonuithread method of activity. They also use the handler internally. It was also mentioned in the source code analysis of Android asynctask in the previous article that the handler is used internally to send the processing result of the task back to the UI thread.

This paper deeply analyzes the message processing mechanism of Android and understands the working principle of handler.

Handler

Let's take a look at the usage of handler through an example.

The above code first creates a new instance of handler and overrides the handlemessage method. In this method, the UI is updated according to the type of message received. Let's take a look at the source code of the handler's construction method:

In the constructor, the looper object is obtained by calling looper. Myloop(). If mloop is empty, an exception will be thrown: "can't create handler inside thread that has not called loop. Prepare()", which means that a handler cannot be created on a thread that does not call loop. Prepare(). The above example does not call this method, but does not throw an exception. In fact, because the main thread has been called for us when it is started, you can directly create a handler. If it is in other sub threads, directly creating a handler will cause the application to crash.

After getting the handler, we get its internal variable mqueue, which is the messagequeue object, that is, the message queue, which is used to save the messages sent by the handler.

So far, all three important roles of Android message mechanism have appeared, namely handler, looper and messagequeue. Generally, the handler we contact more in the code, but looper and messagequeue are indispensable for the handler runtime.

Looper

The last section analyzes the structure of Handler, which calls the Looper.myLooper () method, and the following is its source code:

The code of this method is very simple, which is to get the looper object from sthreadlocal. Sthreadlocal is a ThreadLocal object, which indicates that looper is thread independent.

In the construction of handler, it can be seen from the exception thrown that each thread needs to call the prepare() method to obtain looper. Continue to look at its code:

It is also very simple to set a looper for sthreadlocal. However, it should be noted that if sthreadlocal has been set, an exception will be thrown, that is, a thread will only have one looper. When creating looper, a message queue will be created internally:

The question now is, looper looks very important. What is it exactly? Answer: looper starts the message circulation system and continuously takes messages from the message queue to the handler for processing.

Why do you say so? Take a look at Looper's loop method:

The code of this method is a little long. Don't investigate the details, just look at the overall logic. It can be seen that there is an endless loop inside this method, in which the next message is obtained through the next () method of messagequeue. If it is not obtained, it will be blocked. If the new message is successfully obtained, msg.target.dispatchmessage (MSG) will be called. Msg.target is the handler object (see the next section), and dispatchmessage is the distribution message (already running in the UI thread at this time). The following analyzes the message sending and processing process.

Message sending and processing

When the sub thread sends a message, it calls a series of methods such as SendMessage, sendmessagedelayed and sendmessageattime. Finally, it will call sendmessageattime (message MSG, long uptimemillis). The code is as follows:

This method is to call enqueuemessage to insert a message into the message queue. In enqueuemessage, msg.target will be set as the current handler object.

After the message is inserted into the message queue, Looper is responsible for removing it from the queue and calling the dispatchMessage method of Handler. Next, let's see how this method handles messages:

First, if the callback of the message is not empty, handlecallback processing is called. Otherwise, judge whether the handler's mcallback is empty. If not, call its handlemessage method. If it is still empty, the handler's own handlemessage is called, that is, the method overridden when we create the handler.

If the post (Runnable R) method of Handler is invoked when sending a message, the Runnable is encapsulated to the callback of the message object, and then sendMessageDelayed is invoked. The relevant code is as follows:

At this time, handlecallback will be called in dispatchmessage for processing:

You can see that the run method is called directly to process the message.

If you directly provide a callback object when creating a handler, the message will be handed over to the handlemessage method of this object for processing. Callback is an interface inside the handler:

The above is the flow of message sending and processing. When sending, it is in the sub thread, but when processing, the dispatchmessage method runs in the main thread.

summary

So far, the principle analysis of Android message processing mechanism is over. Now you can see that message processing is completed through handler, looper and messagequeue. The handler is responsible for sending and processing messages. Looper creates a message queue and continuously takes messages from the queue to the handler. Messagequeue is used to save messages.

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

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