⚠️ महत्वपूर्ण नोट
AsyncTask API 30 (Android 11) में डिप्रिकेटेड है। नए प्रोजेक्ट्स के लिए Kotlin Coroutines, RxJava, ExecutorService, या WorkManager का उपयोग करें। यह लेख केवल लीगेसी कोड समझने के लिए है।
AsyncTask क्या था?
AsyncTask एक हेल्पर क्लास थी जो बैकग्राउंड ऑपरेशन करने और परिणाम को UI थ्रेड पर पोस्ट करने की अनुमति देती थी, बिना मैन्युअल थ्रेड/हैंडलर प्रबंधन के।
AsyncTask के 4 चरण
- onPreExecute() - UI थ्रेड पर, बैकग्राउंड कार्य शुरू होने से पहले (प्रोग्रेस बार दिखाएं)
- doInBackground(Params...) - बैकग्राउंड थ्रेड पर, भारी कार्य करें (नेटवर्क, DB, गणना)
- onProgressUpdate(Progress...) - UI थ्रेड पर, प्रोग्रेस अपडेट (publishProgress() से ट्रिगर)
- onPostExecute(Result) - UI थ्रेड पर, कार्य पूरा होने के बाद (परिणाम दिखाएं)
जेनेरिक टाइप्स
AsyncTask// Params - doInBackground इनपुट टाइप // Progress - onProgressUpdate टाइप // Result - doInBackground रिटर्न / onPostExecute इनपुट टाइप
उदाहरण: इमेज डाउनलोड करना
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp">
<Button
android:id="@+id/btnDownload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="इमेज डाउनलोड करें" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:visibility="gone"
style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
<ImageView
android:id="@+id/imageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="16dp"
android:scaleType="centerCrop" />
</LinearLayout>
MainActivity.java
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private Button btnDownload;
private ProgressBar progressBar;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnDownload = findViewById(R.id.btnDownload);
progressBar = findViewById(R.id.progressBar);
imageView = findViewById(R.id.imageView);
btnDownload.setOnClickListener(v -> {
new DownloadImageTask().execute("https://example.com/image.jpg");
});
}
private class DownloadImageTask extends AsyncTask {
@Override
protected void onPreExecute() {
super.onPreExecute();
btnDownload.setEnabled(false);
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
}
@Override
protected Bitmap doInBackground(String... urls) {
String url = urls[0];
try {
URL imageUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) imageUrl.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
// प्रोग्रेस सिमुलेशन (वास्तविक में Content-Length से)
int totalSize = connection.getContentLength();
int downloaded = 0;
byte[] buffer = new byte[1024];
java.io.ByteArrayOutputStream output = new java.io.ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
downloaded += bytesRead;
if (totalSize > 0) {
int progress = (downloaded * 100) / totalSize;
publishProgress(progress);
}
}
byte[] data = output.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
input.close();
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressBar.setProgress(values[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
btnDownload.setEnabled(true);
progressBar.setVisibility(View.GONE);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
Toast.makeText(MainActivity.this, "डाउनलोड पूरा", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "डाउनलोड विफल", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// मेमोरी लीक रोकने के लिए कैंसिल करें
// (वास्तविक कोड में टास्क रेफरेंस रखें)
}
}
AndroidManifest.xml - इंटरनेट परमिशन
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application ...> ... </application>
</manifest>
AsyncTask की समस्याएं
- मेमोरी लीक: एक्टिविटी नष्ट होने पर भी टास्क चलता रहता है और UI रेफरेंस रखता है
- कॉन्फ़िगरेशन चेंज: रोटेशन पर एक्टिविटी रीक्रिएट होती है, टास्क पुरानी एक्टिविटी से जुड़ा रहता है
- सीमित समानांतरता: API 19+ में सीरियल एक्जीक्यूटर (एक समय में एक)
- कोई लाइफसाइकिल अवेयरनेस नहीं: लाइफसाइकिल के साथ ऑटो-कैंसिल नहीं होता
आधुनिक विकल्प
1. Kotlin Coroutines (अनुशंसित)
// ViewModel में
viewModelScope.launch(Dispatchers.IO) {
val bitmap = downloadImage(url)
withContext(Dispatchers.Main) {
imageView.setImageBitmap(bitmap)
}
}
2. ExecutorService + Handler
ExecutorService executor = Executors.newSingleThreadExecutor();
Handler mainHandler = new Handler(Looper.getMainLooper());
executor.execute(() -> {
Bitmap bitmap = downloadImage(url);
mainHandler.post(() -> imageView.setImageBitmap(bitmap));
});
3. WorkManager (डिफर्ड/गारंटीड कार्य)
OneTimeWorkRequest downloadWork = new OneTimeWorkRequest.Builder(DownloadWorker.class)
.setInputData(new Data.Builder().putString("url", url).build())
.build();
WorkManager.getInstance(context).enqueue(downloadWork);
माइग्रेशन चेकलिस्ट
- [ ] AsyncTask उपयोग ढूंढें
- [ ] कार्य प्रकार पहचानें (CPU-बाउंड, IO-बाउंड, डिफर्ड)
- [ ] उपयुक्त आधुनिक API चुनें
- [ ] लाइफसाइकिल अवेयरनेस जोड़ें (ViewModel, LifecycleObserver)
- [ ] एरर हैंडलिंग और रीट्राई लॉजिक जोड़ें
- [ ] टेस्ट करें: रोटेशन, प्रोसेस डेथ, बैकग्राउंड/फोरग्राउंड