我对在Android应用中重复执行AsyncTask的可能性存有疑问。例如,如果由于某些原因无法下载文件,则希望重复执行某些操作,如从服务器下载文件,执行n遍。是否有一种快速的方法可以实现这一点?
我对在Android应用中重复执行AsyncTask的可能性存有疑问。例如,如果由于某些原因无法下载文件,则希望重复执行某些操作,如从服务器下载文件,执行n遍。是否有一种快速的方法可以实现这一点?
您不能重复执行AsyncTask,但是您可以重复执行它执行的操作。
我制作了这个小帮助类,您可能想要扩展它取代AsyncTask,唯一的大区别是您将使用repeatInBackground而不是doInBackground,而onPostExecute将有一个新参数,即最终抛出的异常。
在repeatInBackground内部的任何内容都将自动重复,直到结果不同于null /未抛出异常且尝试次数小于maxTries。
循环内抛出的最后一个异常将在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);
}
}
AsyncTask
对象,因为根据AsyncTask文档,任务只能执行一次(如果尝试进行第二次执行,则会抛出异常)。doInBackground()
中执行下载操作n次。我是用这种方法做的。它可以尝试多次,直到(tries == 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
}
}