Wednesday, 11 November 2015

Using Handlers for async communication in Android

Background

In one of the previous posts we say how Android OS shows ANR(App not responding) if UI threads is blocked for more than 5 seconds. And to overcome this we used Async Tasks.

 In this post we will see how to use handlers which is another mechanism for asynchronous communication.

NOTE : Both handlers and async task internally use threads. So you can achieve the same functionality by pure java threading.

Using Handlers for async communication in Android

Here is what we are going to do. We are going to simulate a 6 seconds task. After that is completed we will send a message to the handler registered on the main thread and it will show a toast message showing task is completed.


To start with we have a simple layout with a button at the center that says "Start Process"

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context=".MainActivity">

    <Button
        android:id="@+id/myButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Process"
        android:layout_centerInParent="true"/>

</RelativeLayout>

Next lets get our handler ready.

import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

/**
 * Created by athakur on 11/11/2015.
 */
public class MainActivityHandler extends Handler {

    public static int SHOW_PROCESS_FINISH_TOAST = 29;

    private Activity activity;
    private static final String TAG = MainActivityHandler.class.getSimpleName();

    public MainActivityHandler(Activity handlerActivity) {
        this.activity = handlerActivity;
    }

    @Override
    public void handleMessage(Message msg) {
        Log.d(TAG, "Received message : " + (msg == null ? null : msg.what));
        switch(msg.what) {
            case 29:
                Toast.makeText(activity,"Finished Processing Task",Toast.LENGTH_LONG).show();
                break;
            default:
                super.handleMessage(msg);
        }
    }
}

This is just a class that extends handler and overrides handleMessage method. It then checks whether the message received is of type process completed show toast type. If so them simply show a toast message saying  "Finished Processing Task".

Now lets see this in action. Write your MainActivity as follows - 

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;


public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button myButton = (Button) findViewById(R.id.myButton);
        final Handler mainActivityHandler = new MainActivityHandler(this);
        myButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG, "Starting process");
                        try {
                            //simulate process for 6 seconds
                            Thread.sleep(6000);
                        } catch (InterruptedException e) {
                            Log.e(TAG,"Thread sleep interrupted",e);
                        }
                        Log.d(TAG, "Ending process. Sending Notification");
                        mainActivityHandler.sendEmptyMessage(MainActivityHandler.SHOW_PROCESS_FINISH_TOAST);
                    }
                }).start();
            }
        });
    }
}


 In the MainActivitys oncreate method we are getting reference of the button and on its onclick we are starting a new thread that does the processing for 6 seconds and then sends a message to the handler that it is done. We are also creating a new handler here.

NOTE1 : Handler is created on main thread or UI thread so it will have messages corresponding to UI threads message queue.

NOTE2 : You cal also post a runnable to be run on the thread to which handler belongs to.

Simply install the app on your phone or emulator and click on "Start Process" button. You should see the process completed toast after 6 seconds without any ANR.



So in a nutshell -

Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue



Realated Links

No comments:

Post a Comment

t> UA-39527780-1 back to top