Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Android

Android AsyncTask उदाहरण और व्याख्या (डिप्रिकेटेड)

⚠️ महत्वपूर्ण नोट

AsyncTask API 30 (Android 11) में डिप्रिकेटेड है। नए प्रोजेक्ट्स के लिए Kotlin Coroutines, RxJava, ExecutorService, या WorkManager का उपयोग करें। यह लेख केवल लीगेसी कोड समझने के लिए है।

AsyncTask क्या था?

AsyncTask एक हेल्पर क्लास थी जो बैकग्राउंड ऑपरेशन करने और परिणाम को UI थ्रेड पर पोस्ट करने की अनुमति देती थी, बिना मैन्युअल थ्रेड/हैंडलर प्रबंधन के।

AsyncTask के 4 चरण

  1. onPreExecute() - UI थ्रेड पर, बैकग्राउंड कार्य शुरू होने से पहले (प्रोग्रेस बार दिखाएं)
  2. doInBackground(Params...) - बैकग्राउंड थ्रेड पर, भारी कार्य करें (नेटवर्क, DB, गणना)
  3. onProgressUpdate(Progress...) - UI थ्रेड पर, प्रोग्रेस अपडेट (publishProgress() से ट्रिगर)
  4. 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)
  • [ ] एरर हैंडलिंग और रीट्राई लॉजिक जोड़ें
  • [ ] टेस्ट करें: रोटेशन, प्रोसेस डेथ, बैकग्राउंड/फोरग्राउंड
  1. Android में स्ट्रिंग को सबस्क्रिप्ट और सुपरस्क्रिप्ट कैसे बनाएं? Android में स्ट्रिंग को सबस्क्रिप्ट और सुपरस्क्रिप्ट कैसे बनाएं?

    SpannableStringBuilder और Span क्लासेज का उपयोग करके टेक्स्ट में सबस्क्रिप्ट (नीचे) और सुपरस्क्रिप्ट (ऊपर) लागू करने का तरीका। चरण 1: नया प्रोजेक्ट बनाएं Android Studio में नया प्रोजेक्ट बनाएं। चरण 2: लेआउट res/layout/activity_main.xml: <?xml version=1.0 encoding=utf-8?> <RelativeLayout x

  1. Android ImageView में जूम-इन और जूम-आउट कैसे करें? Android ImageView में जूम-इन और जूम-आउट कैसे करें?

    ScaleGestureDetector का उपयोग करके ImageView पर पिंच-टू-जूम कार्यक्षमता लागू करने का तरीका। चरण 1: नया प्रोजेक्ट बनाएं Android Studio में नया प्रोजेक्ट बनाएं। चरण 2: लेआउट res/layout/activity_main.xml: <?xml version=1.0 encoding=utf-8?> <LinearLayout xmlns:android=https://schemas.android.

  1. Android में AsyncTask के लिए टाइमआउट कैसे सेट करें? Android में AsyncTask के लिए टाइमआउट कैसे सेट करें?

    परिचय यह ट्यूटोरियल दिखाता है कि AsyncTask के लिए टाइमआउट कैसे सेट करें। ध्यान दें: AsyncTask API 30 (Android 11) में डिप्रिकेटेड है। आधुनिक ऐप्स के लिए Coroutines, RxJava, या ExecutorService उपयोग करें। यह उदाहरण केवल लिगेसी कोड समझने के लिए है। आवश्यक चरण चरण 1: नया प्रोजेक्ट बनाएं Android Studi