आप AsyncTask में कई आदिम पैरामीटर कैसे पास कर सकते हैं?


82

संबंधित प्रश्न हैं, जैसे मैं AsyncTask वर्ग में 2 मापदंडों में कैसे पास कर सकता हूं? , लेकिन मैं एक AsyncTask के मापदंडों के रूप में कई प्राथमिकताओं को पारित करने के लिए व्यर्थ में कोशिश करने की कठिनाई में भाग गया, इसलिए मैं जो कुछ भी खोजता हूं उसे साझा करना चाहता हूं। इस सूक्ष्मता को मौजूदा प्रश्नों और उत्तरों में कैद नहीं किया गया है, इसलिए मैं किसी भी व्यक्ति की मदद करना चाहता हूं जो उसी समस्या में चलता है जैसा मैंने किया था और उन्हें दर्द से बचाता है।

सवाल यह है: मेरे पास कई आदिम पैरामीटर हैं (उदाहरण दो लोंग) जो मैं पृष्ठभूमि में निष्पादित करने के लिए एक AsyncTask को पास करना चाहता हूं - यह कैसे किया जा सकता है? (मेरा जवाब ... थोड़ी देर के लिए इसके साथ संघर्ष करने के बाद ... नीचे पाया जा सकता है।)


जवाबों:


154

बस एक साधारण कंटेनर में अपने आदिम लपेटो और AsyncTaskइस तरह से एक पैरामीटर के रूप में पारित :

private static class MyTaskParams {
    int foo;
    long bar;
    double arple;

    MyTaskParams(int foo, long bar, double arple) {
        this.foo = foo;
        this.bar = bar;
        this.arple = arple;
    }
}

private class MyTask extends AsyncTask<MyTaskParams, Void, Void> {
    @Override
    protected void doInBackground(MyTaskParams... params) {
        int foo = params[0].foo;
        long bar = params[0].bar;
        double arple = params[0].arple;
        ...
    }
}

इसे इस तरह से कॉल करें:

MyTaskParams params = new MyTaskParams(foo, bar, arple);
MyTask myTask = new MyTask();
myTask.execute(params);

यह भी काम करता है। लेकिन मेरा मानना ​​है कि उपरोक्त विकल्प सरल हैं।
रोबगिननेस

10
यह मुझे वास्तव में एक बहुत अच्छे व्यक्ति के रूप में प्रभावित करता है। मैं ऑब्जेक्ट का उपयोग कर रहा हूं ... इसे करने का तरीका और किसी कारण से यह सिर्फ करने के लिए अच्छा या सुरक्षित महसूस नहीं करता है।
Mafro34

1
आकर्षण दोस्त की तरह काम कर रहा है..धन्यवाद साझा करने के लिए ..!
दीपक एस। गावकर

2
बहुत खूबसूरत है, इसे प्यार करो।
सिप्टी

1
@DavidWasser: दिए गए समाधान के अलावा, आपके अपडेट के लिए thanx बहुत बढ़िया काम करता है!
मौसा

93

दूसरा तरीका: आपको अपने MyTask वर्ग में MyTask कंस्ट्रक्टर को जोड़ने की आवश्यकता है:

private class MyTask extends AsyncTask<String, Void, Void> {
    int foo;
    long bar;
    double arple;

    MyTask(int foo, long bar, double arple) { 
         // list all the parameters like in normal class define
        this.foo = foo;
        this.bar = bar;
        this.arple = arple;
    }
    ......   // Here is doInBackground etc. as you did before
}

फिर कॉल करो

new MyTask(int foo, long bar, double arple).execute();

डेविड वासर के उत्तर की तरह दूसरा तरीका।


9
वास्तव में यह विभिन्न प्रकार के तर्कों को पारित करने के लिए तीनों का मेरा पसंदीदा तरीका है। न कोई कास्ट करने की वस्तु और न ही अतिरिक्त क्लास बनाने की आवश्यकता।
क्विकफिक्स

3
आपको अपने ओवरराइड कंस्ट्रक्टर में सुपर () कॉल करने की आवश्यकता है!
zyamys

2
@zyamys सुपर () यहाँ क्यों आवश्यक है? जैसा कि मैं इसे समझता हूं, इसे स्वचालित रूप से कहा जाएगा। यहां देखें stackoverflow.com/a/2054040/984263
कार्थर्स

इस धागे के विकल्पों में से मुझे यह सबसे अच्छा लगता है। कोई सहायक वर्ग नहीं है, इस वर्ग का उपयोग स्वयं किया जा सकता है और अपनी आवश्यकताओं का वर्णन करता है। कोई रहस्य वस्तुओं के आसपास पारित किया जा रहा है। धन्यवाद।
विनीक 12

यह काम। बहुत गंदा लगता है, लेकिन मैं कुछ और करने की कोशिश में बहुत आलसी हूं। विश्वास नहीं कर सकता कि यह मूल रूप से करने के लिए एक अच्छा देशी तरीका नहीं है। संभवतः जावा में बाद में समर्थन कर सकता है<(String,Object,int),Void,Void>
सायरन

82

यह (कड़ाई से बोल रहा है) AsyncTask के लिए कई आदिम पारित करने के लिए संभव नहीं है। उदाहरण के लिए, यदि आप प्रदर्शन करना चाहते हैं myTask.execute(long1, long2)और private class myTask extends AsyncTask<long, Void, Void>संबंधित विधि के साथ सेट करने का प्रयास करते हैं :

@Override
protected LocationItemizedOverlay doInBackground(long... params) {...}

आपकी आईडीई को सुपरपाइप विधि को ओवरराइड करने की आवश्यकता के बारे में शिकायत होगी। ध्यान दें कि आप तथाकथित वर्गास विधि हस्ताक्षर का उपयोग कर रहे हैं doInBackground, जहां (long... params)यह कहने जैसा है "मैं एक लंबी संख्या के चर को स्वीकार करता हूं, जिसे एक सरणी के रूप में संग्रहीत किया जाता है। मुझे पूरी तरह से समझ में नहीं आता है कि एक कंपाइलर / आईडीई शिकायत क्या कारण बनता है। , लेकिन मुझे लगता है कि यह सामान्य वर्ग Paramsको कैसे परिभाषित किया जाता है, इसके साथ करना है।

किसी भी मामले में, आप जो भी समस्या चाहते हैं, उसे प्राप्त करना संभव है, बशर्ते आप अपने आदिम को अपने संबंधित गैर-आदिम आवरणों (जैसे int => पूर्णांक, लंबे => लंबे, आदि) के लिए सही ढंग से कास्ट करें। असल में, आपको अपनी प्राथमिकताओं को स्पष्ट रूप से गैर-प्राथमिकताओं में डालने की आवश्यकता नहीं है। जावा आपके लिए संभालता है। आपको बस अपना ASyncTask इस प्रकार सेट करना है (उदाहरणों के लिए):

private class MyTask extends AsyncTask<Long, Void, Void> {

    @Override
    protected void doInBackground(Long... params) {
        // Do stuff with params, for example:
        long myFirstParam = params[0]
    }
    ...
}

आप इस वर्ग का उपयोग तब कर सकते हैं जब आप मूल रूप से इरादा रखते थे, जैसे:

MyTask myTask = new MyTask();
myTask.execute(long1, long2);

या आपके द्वारा पसंद किए जाने वाले किसी भी संख्या के लिए, वे समान प्रकार के हैं। यदि आपको कई प्रकार की प्राथमिकताओं को पारित करने की आवश्यकता है, तो यह भी किया जा सकता है, लेकिन आपको उपरोक्त को संशोधित करना होगा:

private class MyTask extends AsyncTask<Object, Void, Void> {

    @Override
    protected void doInBackground(Object... params) {
        // Do stuff with params, for example:
        long myLongParam = (Long) params[0];
        int myIntParam = (Integer) params[1];

    }
    ...
}

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


आप विधि के लिए निम्न का भी उपयोग कर सकते हैं protected LocationItemizedOverlay doInBackground(Object[] objects) और एस्किंक टास्क की परिभाषा के लिए निम्नलिखित जोड़ सकते हैं। private class MyTask extends AsyncTask<Object, Void, Void>
हनी सकर

8

विधि पर अमल में बनाया की एक सरणी स्वीकार करता पैरामीटर , लेकिन वे सभी परिभाषित प्रकार का होना चाहिए .. यदि ऐसा है तो आप बस सेट PARAM के लिए प्रकार वस्तु है, तो आप जो कुछ भी आप जब तक वे वस्तुओं के बच्चे हैं चाहते पारित कर सकते हैं। ...

private class MyTask extends AsyncTask<Object, Void, Void> {

फिर अपने doInBackGround में, आप बस प्रत्येक पैराम को वापस उसी क्रम में डालते हैं, जो आपको इसकी आवश्यकता है:

 @Override
 protected void doInBackground(Object... params) {
     Context t = (Context)params[0];
     String a = (String) params[1];
     List<LatLng> list = (List<LatLng>)params[2];
     .
     .
     .

और आपका अमल बस है:

 new MyTask().execute(context,somestring,list_of_points);

अपने स्वयं के रैपर वर्ग, या एक बंडल, या हैश या कुछ और में लपेटने के रूप में उतना अच्छा रूप नहीं है, क्योंकि आप दोनों पक्षों पर निर्भर हैं, लेकिन यह काम करेगा। बेशक आप बस अपने सरणी को हाशपैम (), का एक पैराम बना सकते हैं और आप मूल रूप से उस बिंदु पर एक बंडल को लागू करने के लिए कस्टम हैं, लेकिन यह काम करेगा।


1
यहाँ के लोग इतने सारे शांत टेकनीक के साथ बहुत अच्छे हैं और यह मेरा पसंदीदा था!
जॉर्ज उडोसन

7

मुझे मैलाज़ी की विधि पसंद है, लेकिन अगर आपने ऐसा नहीं किया, तो क्या आप बंडल क्लास का उपयोग नहीं कर सकते?

 Bundle myBundle = new Bundle();
 myBundle.putInt("foo", foo);
 myBundle.putLong("bar", bar);
 myBundle.putDouble("arple", arple);

फिर बस बंडल पास करें और इसे MyTask के अंदर अनपैक करें। क्या यह एक भयानक विचार है? आप एक कस्टम क्लास बनाने से बचते हैं, और यदि आप तय करते हैं कि आप बाद में अतिरिक्त मापदंडों को पास करना चाहते हैं तो यह लचीला है।

अपडेट: मुझे यह जवाब लिखे हुए काफी साल हो चुके हैं, और मैं वास्तव में अब इसे नापसंद करता हूं। मैं एक बंडल का उपयोग करने के खिलाफ सलाह दूंगा। यदि आपको कई मापदंडों को एक एसिंक्टस्क (या कुछ भी, वास्तव में) में पारित करने की आवश्यकता है, तो एक कस्टम वर्ग का उपयोग करें जो आपके सभी मापदंडों को एक साथ रखता है। एक बंडल का उपयोग एक समस्या का एक अच्छा समाधान है जो आपको नहीं होना चाहिए। कस्टम क्लास बनाने के खिलाफ कोई क़ानून नहीं है कि आपको क्या चाहिए, और कुछ नहीं।

इसके अलावा, आप कोरटाइन का उपयोग क्यों नहीं कर रहे हैं? एसिंक्चुअल्स तो 2014 हैं।


महान विचार। हालांकि मैं मानता हूं कि यह कस्टम ऑब्जेक्ट्स को doInBackground () में पारित होने से समर्थन नहीं करता है
जॉन वार्ड

1

यह उपवर्ग के माध्यम से हल किया जाता है। Google के पास इस समस्या को हल करने के लिए एक उदाहरण है (उपवर्ग) आधिकारिक Android AsyncTask प्रलेखन में:

http://developer.android.com/reference/android/os/AsyncTask.html

उदाहरण:

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");
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.