Android advanced advanced in-depth analysis of the message mechanism

Android advanced advanced in-depth analysis of the message mechanism

Reading time: 8 minutes

Are you sitting still? Going to drive


Write in front

The content shared today is an in-depth analysis of Android's message mechanism. Some people have asked, will some functions be used? Why analyze the underlying source code? What Xiaolu tells you today is that many open source projects don’t need us to build wheels anymore, and how stupid it is to rebuild wheels. However, the underlying source code of Android and the realization of some functions allow us to learn the underlying pattern and logic implementation.

The most important thing about learning programming is logical thinking. Even if you can achieve any function, you can't do anything with poor logical thinking ability. Your logical thinking ability is poor, and your height has been determined in the technical route.

Android's message mechanism

Android's message mechanism mainly means that the operation of Handlerr needs the support of the underlying MessageQueue and Looper.

(1) The Chinese translation of MessageQueue is a message queue. Provide insert and delete work externally in the form of a queue. Although it is called a message queue, the internal storage structure is not a real queue, but a singly linked list data structure to store the message list.

(2) Looper's Chinese translation is loop, we call it message loop. Since MessageQueue is just a storage unit, it will not process messages. Looper does make up for this function. Looper will look for new messages in an infinite loop, and process the messages if there are, otherwise it will wait forever.

Learning mind map:

The mind maps in the future articles are carefully organized by Xiaolu for everyone, so that each shared article has a clear structure, which is conducive to review and organization.

Android advanced advanced in-depth analysis of the message mechanism

1. Overview of Android message mechanism

Android message mechanism mainly refers to the operating mechanism of Handler and the working process of MessageQueue and Looper attached to Handler. The main function of Handler is to switch a task to a specified thread for execution.

Overview

(1) Thinking: Why does Android provide this function?

Answer: Because Android stipulates that the UI thread can only be accessed in the main thread, if the UI is accessed in the child thread, the program will throw an exception.

(2) Source code: After checking the source code, the checkThread() method checks whether the update UI is updated in the main thread, and throws an exception message to remind the developer (I believe this has been encountered in development).

(3) Process: Due to the above restrictions, this requires developers to update the UI in the main thread, but Android also recommends not to do too time-consuming work in the main thread, otherwise the application will not respond to ANR. Considering this situation, when we pull some information from the server and display it on the UI, we will do the pull work in the child thread. After the pull is completed, the UI cannot be directly updated in the child thread. Without Handler, then we There is indeed no way to switch the work of accessing the UI to the main thread for execution. Therefore, the main reason why the system provides us with Handler is to solve the contradiction that the UI cannot be accessed in the child thread.

(4) Question:

① 为什么不能再子线程中更新 UI? 
答 : 因为 Android 的 UI 控件不是线性安全的。如果在多线程中并发的访问可能会导致 UI 控件处于不可预期的状态。

② 为什么不对 UI 控件的访问加上锁机制呢? 

答 :首先,加上锁机制会让访问 UI 变的复杂,其次锁机制会降低 UI 的访问效率,因为锁机制会阻塞某些线程的执行。

The simplest and most efficient way is to use a single-threaded model to handle UI operations. You only need to switch the execution thread of UI access through the Handlerr.

How Handler works

When the Handler is created, the current Looper will be used to build the internal message loop system. If there is no Looper currently, an error will be reported.

How to solve the above problems? Two methods:

① Just create Looper for the current thread.
② It is also possible to create a Handler in Looper's thread.

working principle

(1) Handler creation process: After the Handler is created, the internal MessageQueue and Looper work together with the Handler, and then a Runnable is delivered to the Looper inside the Handler for processing through the Handler’s post method; it can also be processed through the Handler’s send The method sends a message, which is also processed by Looper. In fact, the Post method is finally completed by the send method..

(2) The working process of the send method: When the send method of the Handler is called, it will call the enqueueMessage method of MessageQueue to put the message in the message queue, and then Looper will process the message when it finds a new message, and finally the Runnable of the message Or the handlerMessage method of Handler will be called.

Android advanced advanced in-depth analysis of the message mechanism

Two, Android's message mechanism analysis

How the message queue works

Message queue in Android mainly refers to MessageQueue, MessageQueue mainly includes two operations: insert and delete. The internal implementation of the message queue is not a queue. In fact, the message queue is maintained through the data structure of a singly linked list. The singly linked list has advantages in insertion and deletion.

① Insert (enqueueMessage): insert a message into the message queue. (The source code implementation is the insertion of a singly linked list)

② Delete (next): Take out a message from the message queue and remove it from the message queue. (Next is an infinite loop method, the message queue is blocked without information, and the singly linked list is deleted when a new message arrives)

How Lopper works

Looper plays the role of message loop in the Android message mechanism. Its role is to constantly check whether there are new messages from the MessageQueue. If there are messages, they will be processed immediately, and if there are no messages, they will be blocked.

(1) Looper construction method

① Create a MessageQueue message queue.

② Save the object of the current thread.

(2) How to create Looper for a thread

(Handle work requires Looper, without Looper, an error will be reported)

 ① 通过 Looper.prepare() 方法为线程创建一个 Looper 。

 ② 通过 Looper.loop() 方法来开启消息循环。

(3) Another way to create threads

① 主线程 Looper 的获取。 Looper 这个方法主要给线程也就是 ActivityThread 创建 Looper 使用的,本质也是通过 prepare 来实现的,由于主线程的 Looper 比较特殊,所以 Looper 提供了一个 getMainLopper 的方法获取主线程的 Looper。

② Looper 的退出。****Looper 提供了两个方法:quit 方法和 quitSafely 方法。

The difference between the two: Quit exits Looper directly.

And quitSafely just sets an exit mark, and then exits after processing the messages in the message queue.

(4) The realization principle of Looper.loop() method

loop 是一个死循环,唯一能跳出循环的方法就是 MessageQueue 的 next 方法返回了 null。当 Looper 的 quit 方法被调用时,MessageQueue 的 quit 方法或者 quitSafely 方法就会通知消息队列退出,当消息队列被标记为退出状态时,next 就会返回一个 null。Looper 是必须退出的,否则 loop 会永远循环下去。 

The loop method will call the next method of MessageQueue to get the message. If the MessageQueue has no messages, the next will be in a blocking state, and the loop method will also be in a blocking state.

Explain the working principle of Handler in detail

The main job of Handler is to send and receive messages. The message can be sent through a series of post methods and a series of send methods. The series of post methods are finally realized through a series of send methods.

Code:


 1public class HandlerActivity extends Activity {
 2
 3    @Override
 4    protected void onCreate(@Nullable Bundle savedInstanceState) {
 5        super.onCreate(savedInstanceState);
 6        setContentView(R.layout.activity_main);
 7
 8        //开启线程
 9        handler();
10    }
11    //主线程
12    Handler handler = new Handler(){
13
14        @Override
15        public void handleMessage(Message msg) {
16            super.handleMessage(msg);
17            switch (msg.what) {
18                case 1:
19                    // 获取Message里面的复杂数据
20                    Bundle date = new Bundle();
21                    date = msg.getData();
22                    String name = date.getString("name");
23                    int age = date.getInt("age");
24                    String sex = date.getString("sex");
25                    //这里是主线程,可进行对UI的更新
26                    textView.setText(name)
27            }
28        }
29    };
30
31    //子线程
32    public void handler(){
33        new Thread(new Runnable() {
34            @Override
35            public void run() {
36                Message message = new Message();
37                message.what = 1;
38
39                // Message对象保存的数据是Bundle类型的
40                Bundle data = new Bundle();
41                data.putString("name", "李文志");
42                data.putInt("age", 18);
43                data.putString("sex", "男");
44                // 把数据保存到Message对象中
45                message.setData(data);
46                // 使用Handler对象发送消息
47                handler.sendMessage(message);
48            }
49        }).start();
50    }
51}

send messages

Through the source code analysis, the process of Handler sending a message is only to insert a piece of information into the message queue, and the next method of MessageQueue will return this piece of information to Looper, and Looper will process it immediately after receiving the message, and Looper will hand it over to Handler to process the message , Handler's dispatchMessage method will be called, and then Handler will enter the message processing stage.

Message processing

Android advanced advanced in-depth analysis of the message mechanism

In-depth analysis of the source code of dispatchMessage, the Handler processes the message as follows:

① First check whether the callback of Message is null, if it is not null, process the message through handlerCallback. (Message's callback is a Runnable d object, which is actually the Runnable parameter passed by the post method)

② Secondly, check whether mCallback is null. If it is not null, call the handlerMessage method of mCallback to process the message. Callback is an interface.

③ Through Callback, we can use the following methods to create Handle objects.


1Handler handler = new Handler(callback);

The meaning of this creation is to create an instance but does not need to derive a subclass of Handler.

④ However, in our daily development, we often derive a subclass of Handler and override its handleMessage method to process specific messages. If you don't want to create a derived subclass, you can use Callback.

Main thread's message loop

The main thread of Android is ActivityThread. The entry method of the main thread is main. In the main method, the system will use Looper.prepareMainLooper(); to create the Looper and MessageQueue of the main thread, and use Looper.loop() to open the message of the main thread cycle.

After the message loop of the main thread starts, ActivityThread also needs a Handler to interact with the message queue. This Handler is ActivityThread.H. ActivityThread communicates between processes through ApplicationThread and AMS. After AMS completes the request of ActvityThread by means of inter-process communication, it will call back the Binder method in ApplicationThread, and then ApplicationThread will send a message to H, and H will switch the logic in ApplicationThread to ActivityThread after receiving the message. Execute in the middle, that is, switch to the main thread for execution. This process is the message loop model of the main thread.

Guess you like

Origin blog.51cto.com/15064450/2602814