Overview
This documentation explains how to download an image in Android using AsyncTask while displaying a progress dialog during the download process. This approach is commonly found in legacy Android applications and interview-based questions.
Although modern Android development prefers alternatives such as WorkManager, Executors, or networking libraries, AsyncTask is still relevant for maintaining older codebases and understanding Android threading fundamentals.
Understanding Android AsyncTask
AsyncTask enables background execution without directly managing threads. It provides a simplified mechanism to perform background operations and publish results on the UI thread.
AsyncTask should be used only for:
- Short-lived background tasks
- Lightweight operations lasting a few seconds
- UI-related background work
AsyncTask is not suitable for long-running operations or tasks that must survive configuration changes.
AsyncTask Lifecycle and Generic Types
An AsyncTask is defined using three generic parameters:
- Params – Input parameters passed to the task
- Progress – Progress units published during execution
- Result – Result returned after background execution
If a parameter is unused, it should be declared as Void.
AsyncTask Execution Flow
onPreExecute()
Executed on the UI thread before background execution begins.
Used to initialize UI elements such as progress dialogs.
doInBackground()
Runs on a background thread.
Used to perform network or disk operations.
Progress updates can be sent using publishProgress().
onProgressUpdate()
Receives progress updates on the UI thread.
Useful for updating progress bars or UI indicators.
onPostExecute()
Runs on the UI thread after background processing completes.
Used to update UI with the result.
Layout XML for Image Download
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:id="@+id/downloadButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Click Here to Download" />
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="Downloaded image will appear here" />
</LinearLayout>
Downloading Image Using AsyncTask
Activity Implementation
package com.javatechig.droid;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class ImageDownloaderActivity extends Activity {
private ImageView downloadedImage;
private ProgressDialog progressDialog;
private static final String IMAGE_URL =
"http://javatechig.com/sample-images/sample.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.asynch);
Button downloadButton = findViewById(R.id.downloadButton);
downloadedImage = findViewById(R.id.imageView);
downloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new ImageDownloaderTask().execute(IMAGE_URL);
}
});
}
private class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
@Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(
ImageDownloaderActivity.this,
"Please wait",
"Downloading image...");
}
@Override
protected Bitmap doInBackground(String... params) {
return downloadBitmap(params[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (bitmap != null) {
downloadedImage.setImageBitmap(bitmap);
}
progressDialog.dismiss();
}
private Bitmap downloadBitmap(String url) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
try {
HttpResponse response = client.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.e("ImageDownloader", "Failed with status code: " + statusCode);
return null;
}
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = entity.getContent();
try {
return BitmapFactory.decodeStream(inputStream);
} finally {
inputStream.close();
entity.consumeContent();
}
}
} catch (Exception e) {
request.abort();
Log.e("ImageDownloader", "Error downloading image", e);
}
return null;
}
}
}
Key Technical Notes
- Network operations must never run on the UI thread
- ProgressDialog should be dismissed inside
onPostExecute() - Always validate HTTP response status codes
- AsyncTask can be cancelled using
cancel(boolean)when required - This pattern is primarily useful for legacy Android maintenance and interviews


