Android Handler routine (sendMessage and post)

Handler application scenarios

In Android, only the main thread can perform UI operations. It shows that the modification of the UI cannot be implemented in the sub-thread, so Android must support a thread communication mechanism, so that the sub-thread can send a message to let the main thread change the UI. This solution is the handler.

Android neutron threads also need to communicate, and the communication scheme is also a handler.

message mechanism

The communication mechanism is divided into four parts:

message: The information carrier used to transfer in the thread.

messagequeue: The queue for storing messages. The communication mechanism is asynchronous, that is to say, storing messages and fetching messages are independent operations, which is essentially a producer-consumer model.

handler: the implementation of the receiver and sender. It can be understood as a mobile phone, which can send messages and receive messages.

looper: The circular scheduler of the message queue, which is responsible for automatically distributing the messages in the message queue to the corresponding receivers.

All code 1

package com.example.handlertest;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {
    private TextView textView;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView = findViewById(R.id.text1);

        //匿名内部类创建Handler对象
        handler = new Handler(){
            //重写handleMessage函数对收到的消息进行处理
            @Override
            public void handleMessage(Message message){
                switch (message.what){//根据消息标识进行处理
                    case 1:
                        textView.setText("Thread 1!");
                        break;
                    case 2:
                        textView.setText("Thread 2!");
                        break;
                    default:
                        break;
                }
            }
        };

        //创建新的子线程1
        new Thread(){
            @Override
            public void run(){
                try {
                    //延时
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //创建消息对象
                Message message = Message.obtain();
                //设定消息标识
                message.what = 1;
                //通过handler将消息发送到消息队列中
                handler.sendMessage(message);
            }
        }.start();//开启线程


        //创建新的子线程2
        new Thread(){
            @Override
            public void run(){
                try {
                    //延时,和线程1错开
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //创建消息对象
                Message message = Message.obtain();
                //设定消息标识
                message.what = 2;
                //通过handler将消息发送到消息队列中
                handler.sendMessage(message);
            }
        }.start();//开启线程
    }
}

Send messages successively through two threads to change the output of text in the interface.

It should be noted that the two threads themselves are only executed once, and the text changes only twice.

code explanation

There are three threads in the code, the main thread and two sub-threads set by itself.

private Handler handler;

But only one handler object needs to be created, because multiple threads within the process share memory, and the three threads use the same handler instance.

The code in this article uses an anonymous inner class to rewrite the processing function handleMessage in the handler object after receiving the message:


        //匿名内部类创建Handler对象
        handler = new Handler(){
            //重写handleMessage函数对收到的消息进行处理
            @Override
            public void handleMessage(Message message){
                switch (message.what){//根据消息标识进行处理
                    case 1:
                        textView.setText("Thread 1!");
                        break;
                    case 2:
                        textView.setText("Thread 2!");
                        break;
                    default:
                        break;
                }
            }
        };

The instance is created in the main thread, so the processing function is performed in the main thread, and UI modification can be performed.

You can also directly define a subclass of Handler without using an anonymous inner class, and create an object in the main thread. Implement the rewriting of the message processing function in the definition of this class.

                //创建消息对象
                Message message = Message.obtain();
                //设定消息标识
                message.what = 1;
                //通过handler将消息发送到消息队列中
                handler.sendMessage(message);

In the child thread, you only need to create a message object, set the message content, and send it to the message queue.

The message queue messagequeue and the loop controller looper exist implicitly for the developer, and the program only reflects the process of sending and receiving.

All code 2

The way to use post is as follows:

package com.example.handlertest2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    public TextView mTextView;
    public Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextView = (TextView) findViewById(R.id.text1);

        mHandler = new Handler();

        //第一个工作线程
        new Thread(){
            @Override
            public void run(){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //传入runnable对象进行发送
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mTextView.setText("Thread 1!");
                    }
                });
            }
        }.start();

        //第二个工作线程
        new Thread(){
            @Override
            public void run(){
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mTextView.setText("Thread 2!");
                    }
                });
            }
        }.start();
    }
}

The second method does not need to rewrite the Handler, just call its post method.

Guess you like

Origin blog.csdn.net/m0_37872216/article/details/126348676