What is the use of Handler in Android

When an android application is launched the main thread is automatically created. This thread is also called UI thread. This main thread is responsible for everything related to UI i.e drawing the views, dispatching various events and handling the clicks and updating the views. If we perform heavy operations or long running operations UI thread gets blocked and if UI threads blocks for 5 secs or more Android ANR dialog will appear i.e Application not responding.

Handler is a thread which runs on Main UI thread. Handler allows to schedule or repeats the Task at a given interval of time. Handler provides us a way to communicate with the main Thread.

The handler can be used to schedule messages or runnable to executed at some point in the future.

Handler provides us with various methods to execute or to queue the tasks.

Main methods which are used as Follows:-

  1. post(Runnable).
  2. postAtTime(Runnable,long).
  3. postDelayed(Runnable,long).

In Below code, we download the Bitmap in Background thread and then set on Image view in Main Thread

Thread thread=new Thread(new Runnable() {
          @Override
          public void run() {
           // get Bitmap from url in background
             final Bitmap b=getBitmapFromNetwork();

             // setBitmap in UI thread
              profileImage.post(new Runnable() {
                  @Override
                  public void run() {
                      profileImage.setImageBitmap(b);
                  }
              });
            // set Bitmap at particular time 
              new Handler().postAtTime(new Runnable() {
                  @Override
                  public void run() {
                      profileImage.setImageBitmap(b);
                  }
              },SystemClock.uptimeMillis()+1000);

              // set Bitmap after some Delay
              new Handler().postDelayed(new Runnable() {
                  @Override
                  public void run() {
                      profileImage.setImageBitmap(b);
                  }
              },1000);

          }
      });
     thread.start();

The handler can also be used to send Messages to a class or between different activities. This can be as an event notifier or triggers to perform some actions.

Following ways or methods are used to pass messages to Handler.

  1. sendEmptyMessage(int).
  2. sendEmptyMessageAtTime(int,long).
  3. sendEmptyMessageDelayed(int,long).
  4. sendMessage(Message).
  5. sendMessageAtTime(Message,long).
  6. sendMessageDelayed(Message,long).

Let’s see how they work with an example in Same Class.

// on click of a button I am passing int value in sendEmptyMessage to the handler.

sample.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {               
           handler.sendEmptyMessage(0);
           }
       });

the handler will catch the int value in what variable of Message class and we can perform something depending upon the value of what.

handler =new Handler()
        {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                Toast.makeText(MainActivity.this,""+msg.what,Toast.LENGTH_SHORT).show();

                if(msg.what==0)
                {
                    //perform something
                }
                if(msg.what==1)
                {
                    //do something
                }
                else
                {
                    // do something else
                }
            }
        };

// on click of Button i am passing a Bundle object to Message class object and similarly, we can pass a custom object also. similarly, sendMessageAtTime(msg,  uptime) and sendMessageDelayed(msg, delay) can be used to deliver message object at the particular time and after some delay in milliseconds.

sample.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {               
              Message message=new Message();
              Bundle b=new Bundle();
              b.putString("name","abc");
              message.setData(b);
              handler.sendMessage(message);
             }
      });

and handler will receive the Bundle object from Message object and we can perform tasks accordingly.

handler =new Handler()
      {
          @Override
          public void handleMessage(Message msg) {
              super.handleMessage(msg);
              Bundle b=msg.getData();
              Toast.makeText(MainActivity.this,""+b.get("name"),Toast.LENGTH_SHORT).show();
          }
      };

// send messages to the Handler in other Activity(SecondActivity.java) from another activity(MainActivity.java).

SecondActivity.java // the activity containing handler as inner class

/**
 * Created by coderzpassion on 30/06/17.
 */

public class SecondActivity extends AppCompatActivity {

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

    class MyHandler extends Handler
    {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Bundle b=msg.getData();
            Log.e("value",""+b.get("name"));
        }
    }

}

MainActivity.java // the activity to call handler

public class MainActivity extends AppCompatActivity {

    TextView sample;
    ImageView profileImage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sample=(TextView)findViewById(R.id.sample);
        sample.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SecondActivity handler=new SecondActivity();
                SecondActivity.MyHandler handler1=handler. new MyHandler();
                Message message=new Message();
                Bundle b=new Bundle();
                b.putString("name","abc");
                message.setData(b);
                handler1.sendMessage(message);
            }
        });
    }
}

Full code

MainActivity.java

public class MainActivity extends AppCompatActivity {

    TextView sample;
    ImageView profileImage;
    Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sample=(TextView)findViewById(R.id.sample);
        sample.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SecondActivity handler=new SecondActivity();
                SecondActivity.MyHandler handler1=handler. new MyHandler();
                Message message=new Message();
                Bundle b=new Bundle();
                b.putString("name","abc");
                message.setData(b);
                handler1.sendMessage(message);

//            handler.sendEmptyMessage(0);
            }
        });

      handler =new Handler()
        {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
//                Toast.makeText(MainActivity.this,""+msg.what,Toast.LENGTH_SHORT).show();
//
//                if(msg.what==0)
//                {
//                    //perform something
//                }
//                if(msg.what==1)
//                {
//                    //do something
//                }
//                else
//                {
//                    // do something else
//                }
                Bundle b=msg.getData();
                Toast.makeText(MainActivity.this,""+b.get("name"),Toast.LENGTH_SHORT).show();
            }
        };






//        Thread thread=new Thread(new Runnable() {
//            @Override
//            public void run() {
//             // get Bitmap from url in background
//               final Bitmap b=getBitmapFromNetwork();
//
//               // setBitmap in UI thread
//                profileImage.post(new Runnable() {
//                    @Override
//                    public void run() {
//                        profileImage.setImageBitmap(b);
//                    }
//                });
//              // set Bitmap at particular time
//                new Handler().postAtTime(new Runnable() {
//                    @Override
//                    public void run() {
//                        profileImage.setImageBitmap(b);
//                    }
//                }, SystemClock.uptimeMillis()+1000);
//
//                // set Bitmap after some Delay
//                new Handler().postDelayed(new Runnable() {
//                    @Override
//                    public void run() {
//                        profileImage.setImageBitmap(b);
//                    }
//                },1000);
//
//            }
//        });
//       thread.start();
    }
}

SecondActivity.java

public class SecondActivity extends AppCompatActivity {


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

    class MyHandler extends Handler
    {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Bundle b=msg.getData();
            Log.e("value",""+b.get("name"));
        }
    }

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.coderzpassion.handlersample">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SecondActivity"/>
    </application>

</manifest>

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "26.0.0"
    defaultConfig {
        applicationId "com.coderzpassion.handlersample"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation 'com.android.support:appcompat-v7:25.4.0'
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}

Output

handlerandroidexample   handlerandroidtutorial