Detailed Explanation of Android Handler Use Case

  • 2021-12-13 17:21:35
  • OfStack

What is Handler?

Handler can send and process message objects or Runnable objects that are associated with a single thread. Each instance of Handler is associated with 1 thread and its message queue. When an Handler object is created, a thread or message queue is also created, and the Handler object sends and processes these messages or Runnable objects.

The handler class has two main uses:

Execute the Runnable object, and you can also set the delay. Messages are sent between two threads, mainly to send messages to the main thread to update UI.

Why use Handler

To solve the problem of multithreading concurrency, assume that if there are multiple threads updating ui in one activity, and there is no locking mechanism, the interface display will definitely be abnormal. Therefore, andoird officially encapsulates a set of mechanisms to update ui, and handler can also be used to send messages between multiple threads.

How to use Handler

The common methods of handler are as follows:


post ( Runnable ) 
postAtTime ( Runnable , long ) 
postDelayed ( Runnable , long ) 
sendEmptyMessage ( int ) 
sendMessage ( Message ) 
sendMessageAtTime ( Message , long ) 
sendMessageDelayed ( Message , long ) 

We can see that these methods are mainly divided into two categories, one is to pass in an Runnable object, and the other is to pass in an Message object.

Use code to learn post1 Runnable objects

Create an Handler object first, just new1 directly


private Handler handler=new Handler();

Realize Runnable interface, with anonymous implementation, rewrite run method, print a string.


private Runnable runnable=new Runnable() {
        @Override
        public void run() {
            Log.i("MainActivity","Handler Runnable");
        }
};

Then we call the post method of handler. It should be noted here that the bottom layer of post1 Runnable objects uses callbacks and will not open a new thread. All run methods of Runnable are still in the main thread. UI can be updated.


handler.post(runnable);// Execute 
handler.postDelayed(runnable,2000);// Delay 2 Execute in seconds 

Running the program, the log printed by the console is as follows:


05-18 19:17:14.901 17750-17750/com.ansen.handler I/MainActivity: Handler Runnable
05-18 19:17:16.901 17750-17750/com.ansen.handler I/MainActivity: Handler Runnable

From the above log, we can see that the time difference between the two Log is two seconds. This is because when we use the postDelayed method, the second parameter sets a delay of two seconds.

Passing messages using the sendMessage method

From the name of the method, we can understand that it is used to send messages. This method is frequently used in android, because UI cannot be updated in multithreading in Android, and messages must be passed to UI threads through Handler before UI can be updated. Of course, Handler can also be used to send messages to two sub-threads.

We set an id to the TextView control in the activity_main file, then look for this control in MainActivity and assign a value to TextView in a multithreaded for loop. The added code is as follows:


textview= (TextView) findViewById(R.id.textview);
new Thread(new Runnable(){
    @Override
    public void run(){
        for(int i=1;i<=100;i++){
            Log.i("MainActivity"," The current value is :"+i);
            textview.setText(" The current value is :"+i);
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}).start();

Re-run the code and the program collapses. The console prints as follows log:


android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6024)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:820)

This is because UI cannot be updated in multiple threads in android.

When each application starts, Android will start a corresponding main thread to handle things related to UI, such as user's key-pressing events, user's contact with screen events and screen drawing events, and distribute related events to corresponding components for processing, so the main thread is usually called UI thread.

At this time, we will use the Handle class of Android, and Handle can help us solve the problem that multithreading cannot update UI. Here we only need to know how to use this class, and we will introduce its principle in detail later.

Next, let's look at how to use handler to accept messages from child threads in the main thread and update UI. First of all, new1 implements his handleMessage method when Handler, and the modified code is as follows:


private Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        if(msg.what==UPDATE_UI){
            textview.setText(" The current value is :"+msg.obj);
        }
    }
};

We can see that the code for updating TextView is here, and the msg parameter of handleMessage is used. This object we commonly use 1 general on two attributes, what is a label, we send a message must specify the value. obj: Parameters for sending the message.

Let's take a look at what changes have been made to the multithreaded run method. First, call the obtainMessage method. This method returns an Message object from the message pool. If there is no message pool, the object will be created, so as to avoid going straight to the new Message object. The message object has an what attribute that is required to be assigned and is of an int type. As we talked about earlier, it is a sign. obj is a message sent to pass a parameter, and here we pass in the value of i. Finally, the handler. sendMessage (message) method is called. Then the handleMessage method of our handler will be called back.


new Thread(new Runnable(){
            @Override
            public void run(){
                for(int i=1;i<=100;i++){
                    Log.i("MainActivity"," The current value is :"+i);
                    Message message=handler.obtainMessage();
                    message.what=UPDATE_UI;
                    message.obj=i;
                    handler.sendMessage(message);
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
}).start();

There are sendEmptyMessage and sendMessageDelayed methods I will not 11 to explain to you, interested friends to achieve 1.

Source download


Related articles: