Retry AsyncTask
For example I have following AsyncTask:
private class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Void doInBackground(Void... params) {
try {
//some code that may throws exception
return true;
} catch (IOException ex) {
return false;
}
}
@Override
protected void onPostExe开发者_如何学JAVAcute(Boolean param){
if (!param) {
AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);
builder.setMessage("Error");
builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//I want to retry MyAsyncTask here
}
});
builder.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
}
What is best practice to do this? I'm afraid of recursion this code.
You cannot strictly "retry" an instance of AsyncTask
. You have to create a new instance and execute it, just as you did the first one. You should not encounter a recursion problem.
I retry the code within doInBackground()
for x number of times:
@Override
protected Void doInBackground(Void... params)
{
final int MAX_RETRY=3;
int iLoop;
boolean bSuccess=true;
for (iLoop=0; iLoop<MAX_RETRY; iLoop++)
{
try
{
//do some code that throw an exception
//success! exit loop
iLoop=0;
break;
}
catch (IOException ex)
{
bSuccess=false;
}
}
if (iLoop==(MAX_RETRY-1))
{
bSuccess=false;
}
return bSuccess;
}
This is also one of those times when the two values of a boolean are inadequate to measure success. You could replace bSuccess with an enum for a third measure of success: retry later.
I solved the same problem using BetterASyncTask.
It provides the handy HandleError abstract method, which allows me to catch the exception on the UI thread and decide if retry and how.
Please take a look at retryableasynctask and see if it helps.
Usage:
// Params, Progress and Result could be anything, same as a regular AsyncTask
new RetryableAsyncTask<Params, Progress, Result>(myActivity) {
@Override
protected void onPreExecute() {
// write some code here
}
@Override
protected Result doInBackground(Params... params) {
// execute some expensive task here with your params
// eg: MyExpensiveTask with method called 'get'
return MyExpensiveTask.get(params);
}
@Override
protected void onPostExecute(Result result) {
// write some code here with your result
}
}.execute(myParams);
Overriding "onError" behaviour
By the default, onError method shows a dialog "Cancel" and "Retry" button options. However, you might wanna do something else when something goes wrong. To do so, override onError with your own error handling.
// Params, Progress and Result could be anything, same as a regular AsyncTask
new RetryableAsyncTask<Params, Progress, Result>(myActivity) {
// ...
@Override
protected void onError(Throwable error, final Params... params) {
// write your own error handling
}
}.execute(myParams);
精彩评论