android - AsyncTask एंड्रॉइड उदाहरण




android-asynctask (10)

मैं AsyncTask बारे में पढ़ रहा था, और मैंने नीचे दिए गए सरल कार्यक्रम की कोशिश की। लेकिन यह काम नहीं लग रहा है। मैं इसे कैसे कारगर बना सकता हूं?

package com.test;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class AsyncTaskActivity extends Activity {
    Button btn;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener((OnClickListener) this);
    }

    public void onClick(View view){
        new LongOperation().execute("");
    }

    private class LongOperation extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            for(int i=0;i<5;i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }
}

मैं सिर्फ पृष्ठभूमि प्रक्रिया में 5 सेकंड के बाद लेबल बदलने की कोशिश कर रहा हूं।

यह मेरा मुख्य.एक्सएमएल है :

<?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" >
    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:max="10"
        android:padding="10dip">
    </ProgressBar>
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Progress" >
    </Button>
    <TextView android:id="@+id/output"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Replace"/>
</LinearLayout>

अवधारणा और कोड यहाँ

मैंने एंड्रॉइड के AsyncTask का उपयोग करने के लिए एक सरल उदाहरण बनाया है। यह onPreExecute(), doInBackground(), publishProgress() और अंत में onProgressUpdate()

इस doInBackground () पृष्ठभूमि थ्रेड के रूप में काम करता है, जबकि यूआई थ्रेड में अन्य काम करता है। आप doInBackground () में UI तत्व तक नहीं पहुंच सकते हैं। अनुक्रम जैसा मैंने उल्लेख किया है वैसा ही है।

हालांकि अगर आपको doInBackground से किसी भी विजेट को अपडेट करने की आवश्यकता है तो आप doInBackground से doInBackground कर सकते हैं जो आपके UI विजेट को अपडेट करने के लिए onProgressUpdate पर कॉल करेगा।

class TestAsync extends AsyncTask<Void, Integer, String>
{
    String TAG = getClass().getSimpleName();

    protected void onPreExecute (){
        super.onPreExecute();
        Log.d(TAG + " PreExceute","On pre Exceute......");
    }

    protected String doInBackground(Void...arg0) {
        Log.d(TAG + " DoINBackGround","On doInBackground...");

        for(int i=0; i<10; i++){
            Integer in = new Integer(i);
            publishProgress(i);
        }
        return "You are at PostExecute";
    }

    protected void onProgressUpdate(Integer...a){
        super.onProgressUpdate(a);
        Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.d(TAG + " onPostExecute", "" + result);
    }
}

इसे अपनी गतिविधि में इस तरह कॉल करें:

new TestAsync().execute();

यहां डेवलपर संदर्भ


सिद्धांत

AsyncTask आपको UI थ्रेड पर परिणाम प्रकाशित करते समय, पृष्ठभूमि थ्रेड पर कोई कार्य चलाने की अनुमति देता है।

उपयोगकर्ता को हमेशा ऐप से बातचीत करने में सक्षम होना चाहिए और वेब से सामग्री डाउनलोड करने जैसे कार्यों के साथ मुख्य (UI) थ्रेड को अवरुद्ध करने से बचना महत्वपूर्ण है। यह तब होता है जब हम एक AsyncTask उपयोग करेंगे।

यूआई थ्रेड में एक संदेश कतार और एक हैंडलर है जो आपको अन्य धागे से अक्सर चलने योग्य वस्तुओं और संदेशों को भेजने और संसाधित करने की अनुमति देता है। AsyncTask इस व्यवहार को सीधे आगे इंटरफ़ेस के साथ लपेटता है।

कार्यान्वयन

AsyncTask एक सामान्य वर्ग है। (इसका मतलब है कि यह अपने कन्स्ट्रक्टर में पैरामीटरयुक्त प्रकार लेता है। प्रत्येक सामान्य पैरामीटर को तीन चर के साथ जावा चर तर्क के रूप में परिभाषित किया जाता है: ... और इसलिए तकनीकी रूप से सरणी के रूप में पारित किया जाता है)।

AsyncTask द्वारा उपयोग किए जाने वाले तीन प्रकार AsyncTask , Progress , और Result :

  1. पैरा - निष्पादन पर कार्य को भेजे गए पैरामीटर प्रकार
  2. प्रगति - पृष्ठभूमि गणना के दौरान प्रगति अद्यतन करने के लिए प्रकाशित प्रकार
  3. परिणाम - पृष्ठभूमि गणना के परिणाम का प्रकार

ये तीन पैरामीटर तीन प्राथमिक कार्यों से मेल AsyncTask आप AsyncTask में ओवरराइड कर सकते हैं:

  • doInBackground()
  • onProgressUpdate()
  • onPostExecute()

    भी:

  • onPreExecute()

AsyncTask निष्पादित करने के लिए

पृष्ठभूमि कार्य को भेजे जाने वाले पैरामीटर के साथ Execute करें।

क्या होता है

  1. मुख्य / यूआई थ्रेड पर, onPreExecute कहा जाता है। (इस धागे में कुछ शुरू करने के लिए।)
  2. पृष्ठभूमि थ्रेड पर, doInBackground() को निष्पादन फ़ंक्शन पर पारित पैरामीटर के साथ बुलाया जाता है।
    • doInBackground() का उपयोग करने के लिए कम से कम doInBackground() को ओवरराइड करना होगा।
    • जहां लंबे समय तक चलने वाला कार्य होना चाहिए
    • लंबे समय से चलने वाले कार्य की प्रगति के साथ कुछ यूआई अपडेट करने के लिए Progress पैरामीटर के साथ publishProgress() करें publishProgress() को कॉल करें। यह onProgressUpdate() को कॉल करने का कारण बनता है।
  3. पृष्ठभूमि धागे पर, परिणाम को doInBackground() में कार्य से वापस कर दिया जाता है, जो कारण बनता है
  4. मुख्य / यूआई थ्रेड पर, onPostExecute() को लौटा परिणाम के साथ बुलाया जाना चाहिए।

उदाहरण

वेब से कुछ डाउनलोड करने के लिए अवरुद्ध कार्य का उदाहरण फिर से उपयोग करना, निम्न उदाहरण एक छवि डाउनलोड करता है और इसे एक छवि दृश्य में प्रदर्शित करता है। doInBackground() विधि छवि को डाउनलोड करती है और इसे doInBackground() प्रकार के ऑब्जेक्ट में संग्रहीत करती है। onPostExecute() विधि बिटमैप लेती है और इसे ImageView में रखती है।

class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bitImage;

    public DownloadImageTask(ImageView bitImage) {
        this.bitImage = bitImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mBmp = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mBmp = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mBmp;
    }

    protected void onPostExecute(Bitmap result) {
        bitImage.setImageBitmap(result);
    }
}

आपको क्लिकक्लिकलिस्टर बटन को घोषित करने की आवश्यकता है, एक बार क्लिक करें यह AsyncTask क्लास DownloadJson को कॉल करता है, प्रक्रिया नीचे दिखाया जाएगा:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
             new DownloadJson().execute();
            }
        });

    }
     // DownloadJSON AsyncTask
    private class DownloadJson extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected  Void doInBackground(Void... params) {
            newlist = new ArrayList<HashMap<String, String>>();
             json = jsonParser.makeHttpRequest(json, "POST");
            try {
                newarray = new JSONArray(json);
                    for (int i = 0; i < countdisplay; i++) {
                        HashMap<String, String> eachnew = new HashMap<String, String>();
                        newobject = newarray.getJSONObject(i);
                        eachnew.put("id", newobject.getString("ID"));
                        eachnew.put("name", newobject.getString("Name"));
                        newlist.add(eachnew);
                    }
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            newlisttemp.addAll(newlist);
            NewAdapterpager newadapterpager = new NewAdapterpager(ProcesssActivitypager.this,newlisttemp);
            newpager.setAdapter(newadapterpager);
        }
    }

इन दो पंक्तियों को ले जाएं:

TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");

अपने AsyncTask की doInBackground विधि से बाहर और उन्हें onPostExecute विधि में डाल दें। आपका AsyncTask इस तरह कुछ दिखना चाहिए:

private class LongOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        try {
            Thread.sleep(5000); // no need for a loop
        } catch (InterruptedException e) {
            Log.e("LongOperation", "Interrupted", e);
            return "Interrupted";
        }
        return "Executed";
    }      

    @Override
    protected void onPostExecute(String result) {               
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}

जब आप कार्यकर्ता धागे में होते हैं, तो आप सीधे एंड्रॉइड पर यूआई तत्वों का उपयोग नहीं कर सकते हैं।

जब आप AsyncTask का उपयोग कर रहे हैं तो कृपया कॉलबैक विधियों को समझें।

उदाहरण के लिए:

public class MyAyncTask extends AsyncTask<Void, Void, Void>{

    @Override
    protected void onPreExecute() {
        // Here you can show progress bar or something on the similar lines.
        // Since you are in a UI thread here.
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        // After completing execution of given task, control will return here.
        // Hence if you want to populate UI elements with fetched data, do it here.
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        // You can track you progress update here
    }

    @Override
    protected Void doInBackground(Void... params) {
        // Here you are in the worker thread and you are not allowed to access UI thread from here.
        // Here you can perform network operations or any heavy operations you want.
        return null;
    }
}

एफवाईआई: वर्कर थ्रेड से यूआई थ्रेड तक पहुंचने के लिए, आप या तो अपने दृश्य पर runOnUiThread () विधि या पोस्ट विधि का उपयोग करते हैं।

उदाहरण के लिए:

runOnUiThread(new Runnable() {
    textView.setText("something.");
});

or
    yourview.post(new Runnable() {
    yourview.setText("something");
});

इससे आपको चीजों को बेहतर तरीके से जानने में मदद मिलेगी। इसलिए आपके मामले में, आपको अपना टेक्स्टव्यू ऑनपोस्टएक्सक्यूट () विधि में सेट करने की आवश्यकता है।


जब एक अतुल्यकालिक कार्य निष्पादित किया जाता है, तो कार्य 4 चरणों के माध्यम से जाता है:

  1. onPreExecute ()
  2. doInBackground (पैरामीटर ...)
  3. onProgressUpdate (प्रगति ...)
  4. onPostExecute (परिणाम)

नीचे एक डेमो उदाहरण है

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

और एक बार जब आप बनाया, एक कार्य बहुत आसानी से निष्पादित किया जाता है:

 new DownloadFilesTask().execute(url1, url2, url3);

उम्मीद है इससे आपको मदद मिलेगी...


नीचे दिए गए अनुसार अपना कोड बदलें:

@Override
protected void onPostExecute(String result) {

    runOnUiThread(new Runnable() {
        public void run() {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
        }
    });
}

पृष्ठभूमि पृष्ठभूमि के लिए इस लाइब्रेरी का उपयोग करके मैं आपके जीवन को आसान बनाने की सलाह दूंगा https://github.com/Arasthel/AsyncJobLibrary

यह आसान है ..

AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {

    @Override
    public void doOnBackground() {
        startRecording();
    }
});

मेरा पूरा उत्तर here , लेकिन इस पृष्ठ पर अन्य उत्तरों के पूरक के लिए यहां एक व्याख्यात्मक छवि है। मेरे लिए, समझें कि सभी चर कहाँ जा रहे थे शुरुआत में सबसे भ्रमित हिस्सा था।


सीधे शब्दों में:

LongOperation MyTask = new LongOperation();
MyTask.execute();






android-asynctask