logo

This is about how to invoke an Http Url from an android activity.However, this tutorial also shows how to communicate between thread using the Message object.
In this tutorial, we download 1 image from the internet on the click of button on the android phone.

Since fetching data from the internet can be a time-consuming task and a very unpredictable one at that, so, it would best be done in a separate thread rather than the UI/main thread. The basics of this have been discussed in the previous tutorial on Handlers and Threads.

Sample Example for getting image from the internet on the click of Button

So create a project named “com.mobisys.android.get_image_using_handler” having activity “HttpConnectSample“.

So on the click of a button “Get Image”, we want to get an image whose URL is hard-coded in the program. For that first, we must open an HTTP connection to the server and then request for the image.

Hence is the code for opening and making an HTTP Connection:

    private InputStream openHttpConnection(String urlStr) {
    InputStream in = null;
    int resCode = -1;

        try {


            URL url = new URL(urlStr);
            URLConnection urlConn = url.openConnection();

            if (!(urlConn instanceof HttpURLConnection)) {

                throw new IOException ("URL is not an Http URL");

            }

            HttpURLConnection httpConn = (HttpURLConnection)urlConn;
            httpConn.setAllowUserInteraction(false);
            httpConn.setInstanceFollowRedirects(true);
            httpConn.setRequestMethod("GET");
            httpConn.connect();
            resCode = httpConn.getResponseCode();


            if (resCode == HttpURLConnection.HTTP_OK) {

                in = httpConn.getInputStream(); 

            } 

        } catch (MalformedURLException e) {
        e.printStackTrace();
        } catch (IOException e) {
        e.printStackTrace();
        }

    return in;
    }

In brief, we have opened a URLConnection, checked if it is an instance of HttpURLConnection, set the parameters required and made the ‘connection’ finally by calling the connect() method. Then, We check if the response code is OK and get a handle to the input stream.

Our layout(main.xml) will look like

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

	<Button
       android:id="@+id/Button01"
       android:layout_centerHorizontal="true"
       android:layout_width="wrap_content"
       android:layout_alignParentTop="true"
       android:layout_height="wrap_content"
       android:text="Get Image"></Button>

	<ImageView 
	android:id="@+id/imageview01" 
	android:layout_width="fill_parent" 
	android:layout_height="fill_parent" 
	android:layout_below="@id/Button01"
	>
	
	</ImageView>

</RelativeLayout>

Don’t forget to add the permission “android.permission.INTERNET” in “AndroidManifest.xml”

Now, coming to fetching the image. We want to fetch it when the end user clicks on a button “Get Image”. So the code associated with the button click is here:

((Button)findViewById(R.id.Button01)).setOnClickListener(new View.OnClickListener(){

        	@Override
			public void onClick(View v) {
				downloadImage("http://www.android.com/media/wallpaper/gif/android_logo.gif");
		
        	
        }}) ; 

So the fetching of the image is in the downloadImage() method, which is given the URL of the android logo. Here is the method:

private void downloadImage(String urlStr) {
		progressDialog = ProgressDialog.show(this, "", "Fetching Image...");
		final String url = <div style="display:none"></div> urlStr;
		
		new Thread() {
			public void run() {
				InputStream in = null;
				Message msg = Message.obtain();
				try {
				    in = openHttpConnection(url);
				    bitmap = BitmapFactory.decodeStream(in);
				    Bundle b = new Bundle();
				    b.putParcelable("bitmap", bitmap);
				    msg.setData(b);
				    in.close();
				} catch (IOException e1) {
				    e1.printStackTrace();
				}
				messageHandler.sendMessage(msg);	
				
			}
 		}.start();

	}

So, Firstly UI thread shows the ProgressDialog i.e

progressDialog = ProgressDialog.show(this, "", "Fetching Image...");

Then,We start a new thread. WE make the URL string accessible within the new thread by making it a final variable. Since message is an object that we can use for communication between threads, we create a Message object in the thread.

        Message msg = Message.obtain();
   

Then, we bundle our bitmap already fetched into a Bundle object that can be sent back in the Message object.

    Bundle b = new Bundle();

    b.putParcelable("bitmap", bitmap);

    msg.setData(b);

    in.close();

and close the input stream as in.
Then we notify the main/UI thread through this method and also pass on the Message object:

    messageHandler.sendMessage(msg); 

This completes the fetching of the image in a separate thread.As soon as the child thread notifies, the method called back in the main thread is the handleMessage(msg) method. It is in this method that we retrieve the bitmap and set it to the ImageView in the UI.

    private Handler messageHandler = new Handler() {

        public void handleMessage(Message msg) {
        super.handleMessage(msg);
        ImageView img = (ImageView) findViewById(R.id.imageview01);
        img.setImageBitmap((Bitmap)(msg.getData().getParcelable("bitmap")));
        progressDialog.dismiss();
        }

        };

Finally we fetch the data from the msg object through getData(). Then we use the key “bitmap” to retrieve the bitmap and cast it to Bitmap before setting it to the ImageView. Finally, we dismiss the progress dialog.

Run the application.

Download the source code

Click here to download source code.

AUTHOR: Vikas Hiran
No Comments

Leave a Comment

Your email address will not be published.