6

Android 用のアプリケーションで AsyncTask を繰り返す可能性について疑問があります。何らかの理由でファイルをダウンロードできない場合は、サーバーからのファイルのダウンロードなど、いくつかの操作を n 回繰り返したいと思います。これを行う簡単な方法はありますか?

4

3 に答える 3

11

AsyncTask を繰り返すことはできませんが、実行する操作を繰り返すことはできます。

AsyncTask の代わりに拡張したいこの小さなヘルパー クラスを作成しました。唯一の大きな違いは、doInBackground の代わりに repeatInBackground を使用することと、onPostExecute に新しいパラメーター (最終的にスローされる例外) があることです。

結果が null と異なる/例外がスローされず、maxTries 未満になるまで、repeatInBackground 内のすべてが自動的に繰り返されます。

ループ内でスローされた最後の例外は、onPostExecute(Result, Exception) で返されます。

RepeatableAsyncTask(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);
    }
}
于 2013-08-21T13:44:41.160 に答える
0

私はそのようにしました。(tries == MAX_RETRY) または結果が null でなくなるまで試行および試行できます。受け入れられた回答からわずかに変更されたコードで、私にとってはより良いものです。

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
    }

}
于 2015-06-09T08:32:58.677 に答える