2013-03-06 9 views
13

AsyncTask में पैरामीटर के लिए Google varargs का उपयोग करने के कारण क्या हैं? उदाहरण के लिए विधियों execute(), doInBackground() और publishProgress() सभी [Type]... नोटेशन का उपयोग करें।AsyncTask varargs पैरामीटर का उद्देश्य

मुझे लगता है कि यह उपयोग करने के लिए "कठिन" बनाता है ताकि उनके पास कुछ अच्छे कारण हो जिन्हें मैंने अनदेखा किया हो?


तो, हमारे पास हमारे पास कोई पैरामीटर, एक या कई पैरामीटर नहीं हैं। इसे तोड़ने के नीचे दो:

  1. कोई पैरामीटर (आसान): Params पैरामीटर Void है और बस इतना ही। (तरीकों के लिए इसका इस्तेमाल नहीं कर सकते हैं ... तो यह है कि बहुत सुरक्षित है।)

  2. एक पैरामीटर: यहाँ, मैं कम से कम, doInBackground() विधि की शुरुआत में एक जांच करने की आवश्यकता को महसूस करते हैं।

    public Double doInBackground(Integer... myParameters) { 
        // we are only expecting one parameter 
        if (myParameters.length != 1) 
         throw new IllegalArgumentException("!= 1"); 
    
        return 100d * myParameters[0]; 
    } 
    
  3. अधिक एक पैरामीटर से: उदाहरण के लिए, यहाँ एक काम एक Integer प्राप्त करने और प्रकार Double का एक परिणाम के उत्पादन है। अब यहां होना चाहिए जहां Google ने सही विकल्प बनाया था? लेकिन जैसा कि मैंने देखा है या तो आप के पैरामीटर की एक सूची में रुचि रखते हैं, या आप पैरामीटर के विभिन्न प्रकार चाहते हैं। गूगल केवल इन मामलों में से एक को संबोधित किया (विभिन्न प्रकार के साथ आप आम इंटरफेस के कुछ प्रकार की जरूरत है। कई मामलों में मैं Object... साथ खत्म हो और जो वास्तव में सुरक्षित टाइप नहीं है ...)


तो , अगर हम varargs को पूरी तरह हटा दें तो समस्या क्या है? यहां विधियों का सबसेट है:

class AsyncTask<Param, Progress, Result> { 

    abstract Result doInBackground(Param param); 
    void publishProgress(Progress progress) { ... } 
} 

यह उपरोक्त सभी मामलों के लिए काम करेगा।

class MyAsyncTask extends AsyncTask<String[], Integer, String> { 

    String doInBackground(String[] param) { 
     return Arrays.toString(param); 
    } 
} 

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

+0

संभव डुप्लिकेट [जब आप जावा में varargs प्रयोग करते हैं?] (Http://stackoverflow.com/questions/766559/when-do-you-use-varargs -इन-जावा) – CommonsWare

+1

यह प्रश्न उस प्रश्न का डुप्लिकेट क्यों है? यह एक विशिष्ट इंटरफ़ेस है जिसे मैं पूछताछ कर रहा हूं। डेवलपर्स ने इस विशिष्ट समस्या को varargs का उपयोग क्यों किया। मैंने सोचा कि मैंने यह स्पष्ट कर दिया है कि मुझे पता है कि यह क्या है और मैं उचित होने पर इसका उपयोग करता हूं .. :) – dacwe

+0

"यह एक विशिष्ट इंटरफेस है जिसे मैं पूछताछ कर रहा हूं" - आपके तर्कों में कुछ भी नहीं है जिसमें कुछ भी करने के लिए विशिष्ट है 'AsyncTask'। आप 'रेस्तरां' कक्षा के साथ varargs के उपयोग के बारे में शिकायत कर सकते हैं। यदि आपका प्रश्न varargs के प्रभावों पर केंद्रित था, तो कहें, 'AsyncTask' थ्रेड के बीच संचार को कैसे प्रबंधित करता है, तो यह एक डुप्लिकेट नहीं हो सकता है। लेकिन, जैसा कि यह खड़ा है, आईएमएचओ, मैंने जो प्रश्न उद्धृत किया है, उसमें दिए गए उत्तरों में भी इस प्रश्न को शामिल किया जाएगा। – CommonsWare

उत्तर

1

मुझे लगता है कि आप सही हैं, प्रकार पैरामीटर Params का एकमात्र उपयोग Params... में है, जिसका अर्थ है कि यह वास्तव में Params[] है जो यहां चाहता था। हालांकि अब एपीआई केवल सरणी प्रकारों के साथ काम करता है, यह पूरे गैर-सरणी प्रकारों को याद करता है।

varargs का ही लाभ कॉल स्थल पर है, लेकिन यह ज्यादा या तो नहीं है -

गूगल के संस्करण:

AsyncTask<String> task = ... 
task.execute("a", "b"); 

आपका संस्करण:

AsyncTask<List<String>> task = ... 
task.execute(Arrays.asList("a", "b")); 
2

मैं vararg तर्क लगता है AsyncTask निष्पादित करने के लिए कॉल करते समय बस थोड़ा और सुविधाजनक बनाता है।

जब तक हम सोच रहे हैं कि क्यों AsyncTask तरह से डिजाइन किया गया था यह है: :-)

मेरी राय में, Param और Result टेम्पलेट्स ही पूरा करने के लिए नहीं किया गया है वास्तव में जरूरी।

जब आप अपना खुद का AsyncTask लिखते हैं, तो आप इसे उप-वर्गीकृत करते हैं। वास्तविक प्रकारों को Param और Result के लिए घोषित करने के बजाय, आप अपने उप-वर्ग (पैराम्स) में अंतिम फ़ील्ड भी जोड़ सकते हैं और अपने उप-वर्ग (परिणाम) में संशोधित फ़ील्ड जोड़ सकते हैं। E.g:

public class MyAsyncTask extends AsyncTask<Void> { 
    // Input Params 
    private final int inParam1; 
    private final String inParam2; 

    // Output Results 
    private Bitmap resultBitmap; 

    public MyAsyncTask(int param1, String param2) { 
     inParam1 = param1; 
     inParam2 = param2; 
    } 

    @Override 
    protected void doInBackground() { 
     // use param1 and param2 as input to the background process. 
     ... 
     ... 
     // Finished: assign to result 
     resultBitmap = ....; 
    } 

    @Override 
    protected void onPostExecute() { 
     // Send result to UI. 
     ... resultBitmap ... 
     ... 
     resultBitmap = null; 
    } 
} 

प्रगति दिखाने के अलावा शायद कोई जेनरिक आवश्यक नहीं है।

यह वही है जो मैं आमतौर पर करता हूं, खासकर यदि परिणाम Bitmap है। doInBackground द्वारा लौटाया गया मूल्य और onPostExecute द्वारा संचालित सभी सेट और किए जाने के बाद शून्य पर सेट नहीं किया गया है और यह इस तरह से '0x' चुपके से 'लीक' करता है (स्मृति/AsyncTasks द्वारा मेमोरी में आयोजित बिटमैप्स के कारण स्मृति त्रुटियां)।

संबंधित मुद्दे