2013-08-21 8 views
5

दोहराएं मुझे एंड्रॉइड के लिए एप्लिकेशन में AsyncTask को दोहराने की संभावना के बारे में संदेह है। मैं कुछ ऑपरेशन दोहराना चाहता हूं, उदाहरण के लिए सर्वर से फ़ाइल का डाउनलोड, एन टाइम्स अगर फ़ाइल को डाउनलोड करने के कुछ कारणों से असंभव है। ऐसा करने का एक त्वरित तरीका है?AsyncTask

+1

समस्या क्या है? यदि यह विफल हुआ तो आप फिर से उसी AsyncTask को फिर से शुरू कर सकते हैं। –

+0

Async कार्य – Mohit

उत्तर

8

आप एक AsyncTask दोहरा नहीं सकते लेकिन आप इसे निष्पादित किए गए संचालन को दोहरा सकते हैं।

मैंने इस छोटे से सहायक वर्ग को बनाया है जिसे आप AsyncTask के स्थान पर विस्तारित करना चाहते हैं, केवल एक बड़ा अंतर यह है कि आप doInBackground के बजाय repeatInBackground का उपयोग करेंगे और उस पर पोस्टस्टेक्स्यूट का नया पैरामीटर होगा, अंतिम अपवाद फेंक दिया जाएगा।

दोहराने के अंदर कुछ भी बैकग्राउंड स्वचालित रूप से दोहराया जाएगा जब तक कि नल/अपवाद से अलग न हो और अधिकतम मैट्रीज़ से कम न हो।

लूप के अंदर फेंक दिया गया अंतिम अपवाद ऑनपोस्टएक्सक्यूट (परिणाम, अपवाद) में वापस किया जाएगा।

आप दोहराने योग्य एसिंक टास्क (int retries) कन्स्ट्रक्टर का उपयोग कर अधिकतम प्रयास सेट कर सकते हैं।

public abstract class RepeatableAsyncTask<A, B, C> extends AsyncTask<A, B, C> { 
    private static final String TAG = "RepeatableAsyncTask"; 
    public static final int DEFAULT_MAX_RETRY = 5; 

    private int mMaxRetries = DEFAULT_MAX_RETRY; 
    private Exception mException = null; 

    /** 
    * Default constructor 
    */ 
    public RepeatableAsyncTask() { 
     super(); 
    } 

    /** 
    * Constructs an AsyncTask that will repeate itself for max Retries 
    * @param retries Max Retries. 
    */ 
    public RepeatableAsyncTask(int retries) { 
     super(); 
     mMaxRetries = retries; 
    } 

    /** 
    * Will be repeated for max retries while the result is null or an exception is thrown. 
    * @param inputs Same as AsyncTask's 
    * @return Same as AsyncTask's 
    */ 
    protected abstract C repeatInBackground(A...inputs); 

    @Override 
    protected final C doInBackground(A...inputs) { 
     int tries = 0; 
     C result = null; 

     /* This is the main loop, repeatInBackground will be repeated until result will not be null */ 
     while(tries++ < mMaxRetries && result == null) { 
      try { 
       result = repeatInBackground(inputs); 
      } catch (Exception exception) { 
       /* You might want to log the exception everytime, do it here. */ 
       mException = exception; 
      } 
     } 
     return result; 
    } 

    /** 
    * Like onPostExecute but will return an eventual Exception 
    * @param c Result same as AsyncTask 
    * @param exception Exception thrown in the loop, even if the result is not null. 
    */ 
    protected abstract void onPostExecute(C c, Exception exception); 

    @Override 
    protected final void onPostExecute(C c) { 
     super.onPostExecute(c); 
     onPostExecute(c, mException); 
    } 
} 
+0

दोहराने के लिए सेवा और अलाराम प्रबंधक वर्ग का उपयोग करें क्या यह एक स्थिर वर्ग के रूप में काम करता है? मैं अभिविन्यास परिवर्तन के दौरान खतरनाक संदर्भ से बचने के लिए स्थिर AsyncTasks का उपयोग करना पसंद करता हूं। क्या आप जानते हैं कि आपकी कक्षा स्थिर रूप से काम करती है या नहीं? –

+0

मैं हमेशा इसे स्थिर रूप से उपयोग करता हूं। –

1

आप के रूप में ही AsyncTask वस्तु, according to the AsyncTask Docs

कार्य केवल एक बार (यदि एक दूसरे निष्पादन का प्रयास किया है एक अपवाद फेंक दिया जाएगा।)

क्रियान्वित किया जा सकता का पुन: उपयोग नहीं कर सकते लेकिन आप उस लूप के अंदर उस कक्षा की कई नई वस्तुएं बना सकते हैं जिन्हें आपको चाहिए। हालांकि आपके doInBackground() के अंदर डाउनलोड ऑपरेशन एन संख्या को बेहतर तरीके से करने का एक बेहतर तरीका है।

इस तो आपके प्रश्न का उत्तर नहीं है, तो कृपया अपने समस्या यह है कि जिस तरह से

0

मैंने किया है के रूप में अधिक विशिष्ट। यह कोशिश कर सकता है और कोशिश कर सकता है (कोशिश करता है == MAX_RETRY) या नतीजा शून्य नहीं है। स्वीकार्य उत्तर से थोड़ा संशोधित कोड, मेरे लिए बेहतर है।

private class RssReaderTask extends AsyncTask<String, Void, ArrayList<RssItem>> { 

    // max number of tries when something is wrong 
    private static final int MAX_RETRY = 3; 

    @Override 
    protected ArrayList<RssItem> doInBackground(String... params) { 

     ArrayList<RssItem> result = null; 
     int tries = 0; 

     while(tries++ < MAX_RETRY && result == null) { 
      try { 
       Log.i("RssReaderTask", "********** doInBackground: Processing... Trial: " + tries); 
       URL url = new URL(params[0]); 
       RssFeed feed = RssReader.read(url); 
       result = feed.getRssItems(); 
      } catch (Exception ex) { 
       Log.i("RssReaderTask", "********** doInBackground: Feed error!"); 
      } 
     } 

     return result; 
    } 

    @Override 
    protected void onPostExecute(ArrayList<RssItem> result) { 
     // deal with result 
    } 

}