How to Use AsyncTask in Android for Background Operations
Android applications should never perform heavy operations on the main UI thread.
Tasks such as:
- Network requests
- File downloads
- Database processing
- Large calculations
can block the UI and make applications unresponsive.
In this tutorial, we will learn how to use AsyncTask in Android to perform background operations while updating the UI safely.
What Is AsyncTask?
AsyncTask is an Android class used to perform background operations and publish results on the UI thread.
It helps developers avoid manually managing:
- Threads
- Handlers
- Runnable objects
Although AsyncTask is deprecated in modern Android development, understanding it is still useful for maintaining older Android projects.
How AsyncTask Works
An AsyncTask typically contains four important methods:
| Method | Purpose |
|---|---|
| onPreExecute() | Runs before background task starts |
| doInBackground() | Performs heavy background work |
| onProgressUpdate() | Updates progress on UI thread |
| onPostExecute() | Returns result to UI thread |
What We Will Build
In this example:
- User clicks a button
- Background task starts
- ProgressBar updates gradually
- Toast message appears after completion
Step 1 — Create Layout File
Create the UI inside activity_main.xml.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:visibility="invisible"/>
<Button
android:id="@+id/button_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start"/>
</LinearLayout>
Step 2 — Implement MainActivity.java
Open MainActivity.java and add the following code:
package com.example.asynctaskexample;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.lang.ref.WeakReference;
public class MainActivity extends AppCompatActivity {
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progress_bar);
Button buttonStart =
findViewById(R.id.button_start);
buttonStart.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
ExampleAsyncTask task =
new ExampleAsyncTask(
MainActivity.this
);
task.execute(10);
}
});
}
private static class ExampleAsyncTask
extends AsyncTask<Integer, Integer, String> {
private WeakReference<MainActivity>
activityWeakReference;
ExampleAsyncTask(MainActivity activity) {
activityWeakReference =
new WeakReference<>(activity);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
MainActivity activity =
activityWeakReference.get();
if (activity == null
|| activity.isFinishing()) {
return;
}
activity.progressBar
.setVisibility(View.VISIBLE);
}
@Override
protected String doInBackground(
Integer... integers
) {
for (int i = 0;
i < integers[0];
i++) {
publishProgress(
(i * 100) / integers[0]
);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Finished!";
}
@Override
protected void onProgressUpdate(
Integer... values
) {
super.onProgressUpdate(values);
MainActivity activity =
activityWeakReference.get();
if (activity == null
|| activity.isFinishing()) {
return;
}
activity.progressBar
.setProgress(values[0]);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
MainActivity activity =
activityWeakReference.get();
if (activity == null
|| activity.isFinishing()) {
return;
}
Toast.makeText(
activity,
s,
Toast.LENGTH_SHORT
).show();
activity.progressBar.setProgress(0);
activity.progressBar
.setVisibility(View.INVISIBLE);
}
}
}
Why WeakReference Is Important
AsyncTask can continue running even after the Activity is destroyed.
If developers keep a strong Activity reference, memory leaks can happen.
Using:
WeakReference<MainActivity>
helps prevent memory leaks by allowing Android to clean destroyed Activities properly.
How This Example Works
The workflow is:
- User clicks Start button
- AsyncTask starts in background
- Progress updates every second
- ProgressBar updates on UI thread
- Toast appears after completion
Understanding AsyncTask Generic Types
AsyncTask<Params, Progress, Result>
| Type | Purpose |
|---|---|
| Params | Input parameters |
| Progress | Progress updates |
| Result | Final task result |
Common Mistakes Developers Make
1. Updating UI Inside doInBackground()
UI updates should only happen on the main thread.
2. Creating Memory Leaks
Holding strong Activity references can leak destroyed Activities.
3. Running Heavy Infinite Tasks
Long-running operations should use WorkManager or background services instead.
Why AsyncTask Is Deprecated
Google deprecated AsyncTask because:
- Lifecycle handling is difficult
- Memory leaks are common
- Limited threading flexibility
- Poor scalability
Modern Alternatives to AsyncTask
Modern Android applications should use:
- Coroutines
- WorkManager
- RxJava
- Executors
- LiveData + ViewModel
AsyncTask vs Coroutines
| AsyncTask | Coroutines |
|---|---|
| Deprecated | Modern solution |
| Complex lifecycle handling | Lifecycle-aware support |
| More boilerplate | Cleaner asynchronous code |
FAQ
Is AsyncTask still useful in 2026?
Mainly for maintaining older Android projects and interview preparation.
Why should heavy work avoid the UI thread?
Heavy operations can freeze the UI and cause ANR (Application Not Responding) errors.
What is the best replacement for AsyncTask?
Kotlin Coroutines and WorkManager are modern recommended solutions.
Conclusion
AsyncTask helped Android developers perform background operations more easily in older Android applications.
Although deprecated today, understanding AsyncTask is still useful for maintaining legacy projects and understanding Android threading concepts.
Modern Android applications should prefer lifecycle-aware asynchronous solutions such as Coroutines and WorkManager.
About the Author
Salil Jha is a Full Stack and Mobile Developer with experience in Android, React Native, scalable SaaS platforms, fintech systems, and developer tooling applications.
CodeChain Dev — Build Modern Products. Solve Real Problems.
Deep Structural Diagnostics.
Mastering JSON is only the first step. Use our industrial-grade workbench to format, validate, and synthesize models for your production APIs.