开发者

Retry AsyncTask

开发者 https://www.devze.com 2023-02-17 04:17 出处:网络
For example I have following AsyncTask: private class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {

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);
0

精彩评论

暂无评论...
验证码 换一张
取 消