Handler in Android (Part 1)

Introduction 

In Android, we often want to perform long-running tasks using the background thread with the help of a thread class.

Basically, an Android application has two types of threads:

  • Main Thread(UI Thread).
  • Background Thread.

Lets take one example. We want to download a file from a remote server and update the UI progress bar for showing the file downloading status. For that we use a background thread to download the file from a remote server, otherwise, if we initialize a long-running task in Main Thread (UI Thread), the UI will slow

We can achieve the task with the help of background thread. However, the problem is that we want to update the UI from a background thread. The background thread will not allow us to communicate directly to the main thread.

Handler

So, we want a main thread and a background thread to communicate with the help of a Handler.

A handler act as a mediator between the background thread and the main thread.

The main uses of Handler is:

  • To schedule messages and 'runnables' to be executed at some point in the future.
  • To queue an action to be performed on a different thread than your own.
 

Let's see the following example: 

 
 actvity_main.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     xmlns:tools="http://schemas.android.com/tools"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent"  
  7.     tools:context=".MainActivity">  
  8.   
  9.     <Button  
  10.         android:id="@+id/btnStart"  
  11.         android:layout_width="wrap_content"  
  12.         android:layout_height="wrap_content"  
  13.         android:layout_marginStart="160dp"  
  14.         android:layout_marginLeft="160dp"  
  15.         android:layout_marginTop="139dp"  
  16.         android:layout_marginBottom="168dp"  
  17.         android:text="Start"  
  18.         app:layout_constraintBottom_toTopOf="@+id/progressBar"  
  19.         app:layout_constraintStart_toStartOf="parent"  
  20.         app:layout_constraintTop_toTopOf="parent" />  
  21.   
  22.     <ProgressBar  
  23.         android:id="@+id/progressBar"  
  24.         style="?android:attr/progressBarStyleHorizontal"  
  25.         android:layout_width="0dp"  
  26.         android:layout_height="0dp"  
  27.         android:layout_marginStart="27dp"  
  28.         android:layout_marginLeft="27dp"  
  29.         android:layout_marginEnd="27dp"  
  30.         android:layout_marginRight="27dp"  
  31.         android:layout_marginBottom="344dp"  
  32.         app:layout_constraintBottom_toBottomOf="parent"  
  33.         app:layout_constraintEnd_toEndOf="parent"  
  34.         app:layout_constraintStart_toStartOf="parent"  
  35.         app:layout_constraintTop_toBottomOf="@+id/btnStart" />  
  36.   
  37.     <TextView  
  38.         android:id="@+id/txtCount"  
  39.         android:layout_width="match_parent"  
  40.         android:layout_height="wrap_content"  
  41.         android:textAlignment="center"  
  42.         app:layout_constraintBottom_toBottomOf="parent"  
  43.         app:layout_constraintTop_toBottomOf="@+id/progressBar"  
  44.         tools:layout_editor_absoluteX="132dp" />  
  45. </androidx.constraintlayout.widget.ConstraintLayout> 
 
 MainActivity.java
  1. package com.e.handler;  
  2.   
  3. import androidx.appcompat.app.AppCompatActivity;  
  4.   
  5. import android.os.Bundle;  
  6. import android.os.Handler;  
  7. import android.os.Message;  
  8. import android.util.Log;  
  9. import android.view.View;  
  10. import android.widget.Button;  
  11. import android.widget.ProgressBar;  
  12. import android.widget.TextView;  
  13.   
  14. public class MainActivity extends AppCompatActivity implements View.OnClickListener {  
  15.   
  16.   
  17.     private static final String TAG = "MainActivity";  
  18.   
  19.     Button btnStar;  
  20.     ProgressBar progressBar;  
  21.     TextView txtCount;  
  22.   
  23.     int MAX_COUNT = 100;  
  24.     Handler mHandlerThread;  
  25.     private static final int START_PROGRESS = 100;  
  26.     private static final int UPDATE_COUNT = 101;  
  27.   
  28.     Thread thread;  
  29.   
  30.     @Override  
  31.     protected void onCreate(Bundle savedInstanceState) {  
  32.         super.onCreate(savedInstanceState);  
  33.         setContentView(R.layout.activity_main);  
  34.   
  35.   
  36.         btnStar = findViewById(R.id.btnStart);  
  37.         progressBar = findViewById(R.id.progressBar);  
  38.         txtCount = findViewById(R.id.txtCount);  
  39.         progressBar.setMax(MAX_COUNT);  
  40.   
  41.         btnStar.setOnClickListener(this);  
  42.   
  43.         thread = new Thread(new Runnable() {  
  44.             @Override  
  45.             public void run() {  
  46.                 for (int count = 0; count <= 100; count++) {  
  47.                     try {  
  48.                         Thread.sleep(100);  
  49.                     } catch (InterruptedException ex) {  
  50.                         ex.printStackTrace();  
  51.                     }  
  52.                     Message message = new Message();  
  53.                     message.what = UPDATE_COUNT;  
  54.                     message.arg1 = count;  
  55.                     mHandlerThread.sendMessage(message);  
  56.                 }  
  57.             }  
  58.         });  
  59.   
  60.   
  61.     }  
  62.   
  63.     @Override  
  64.     public void onClick(View view) {  
  65.         if (view.getId() == R.id.btnStart) {  
  66.             mHandlerThread.sendEmptyMessage(START_PROGRESS);  
  67.         }  
  68.     }  
  69.   
  70.     @Override  
  71.     protected void onResume() {  
  72.         super.onResume();  
  73.         mHandlerThread = new Handler() {  
  74.             @Override  
  75.             public void handleMessage(Message msg) {  
  76.                 super.handleMessage(msg);  
  77.                 if (msg.what == START_PROGRESS) {  
  78.                     thread.start();  
  79.                 } else if (msg.what == UPDATE_COUNT) {  
  80.                     txtCount.setText("Progress Count : " + msg.arg1);  
  81.                     progressBar.setProgress(msg.arg1);  
  82.                 }  
  83.             }  
  84.         };  
  85.     }  

 

From the above example, we are trying to update UI Thread from the Background thread Using Handler.

Thanks for giving your valuable time to read this document!