Repeat AsyncTask

前端 未结 3 601
情话喂你
情话喂你 2021-01-02 22:10

I have a doubt about the possibility of repeating an AsyncTask in an application for Android. I would like to repeat some operations, the download of a file from a server fo

相关标签:
3条回答
  • 2021-01-02 22:28

    You cannot reuse the same AsyncTask object as, according to the AsyncTask Docs

    The task can be executed only once (an exception will be thrown if a second execution is attempted.)

    But you can create however many new objects of that class you need inside of a loop. However a better way you be to do the download operation n number of times inside your doInBackground().

    If this doesn't answer your question then please be more specific as to your problem

    0 讨论(0)
  • 2021-01-02 22:37

    I did it that way. It can try and try until (tries == MAX_RETRY) or the result is not null. A slightly modified code from accepted answer, better for me.

    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
        }
    
    }
    
    0 讨论(0)
  • 2021-01-02 22:39

    You cannot repeat an AsyncTask but you could repeat the operations it executes.

    I've made this little helper class that you might want to extend in place of AsyncTask, the only big difference is that you will use repeatInBackground instead of doInBackground and that onPostExecute will have a new parameter, the eventual Exception thrown.

    Anything inside repeatInBackground will be repeated automatically until result is different from null / exception is not thrown and there are been less than maxTries.

    The last exception thrown inside the loop will be returned in the onPostExecute(Result, Exception).

    You can set max tries using the RepeatableAsyncTask(int retries) constructor.

    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 讨论(0)
提交回复
热议问题