Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ideal way to cancel an executing AsyncTask

I am running remote audio-file-fetching and audio file playback operations in a background thread using AsyncTask. A Cancellable progress bar is shown for the time the fetch operation runs.

I want to cancel/abort the AsyncTask run when the user cancels (decides against) the operation. What is the ideal way to handle such a case?

like image 970
Samuh Avatar asked Apr 29 '10 06:04

Samuh


People also ask

How do I cancel AsyncTask?

AsynTaskExample mAsyncTask = new AsyncTaskExample(); mAsyncTask. cancel(true);

How do I stop AsyncTask when activity is destroyed?

You can either cancel the AsyncTask in the onStop method of your activity or you can let your async task finish, and not loose its progress and relink it to the next instance of your activity.

When AsyncTask is executed it goes through what steps?

An asynchronous task is defined by 3 generic types, called Params , Progress and Result , and 4 steps, called onPreExecute , doInBackground , onProgressUpdate and onPostExecute .

What happen if we call execute more than once in AsyncTask?

Limitation Of AsyncTask There is a limit of how many tasks can be run simultaneously. Since AsyncTask uses a thread pool executor with max number of worker threads (128) and the delayed tasks queue has fixed size 10. If you try to execute more than 138 AsyncTasks the app will crash with java.


2 Answers

Just discovered that AlertDialogs's boolean cancel(...); I've been using everywhere actually does nothing. Great.
So...

public class MyTask extends AsyncTask<Void, Void, Void> {      private volatile boolean running = true;     private final ProgressDialog progressDialog;      public MyTask(Context ctx) {         progressDialog = gimmeOne(ctx);          progressDialog.setCancelable(true);         progressDialog.setOnCancelListener(new OnCancelListener() {             @Override             public void onCancel(DialogInterface dialog) {                 // actually could set running = false; right here, but I'll                 // stick to contract.                 cancel(true);             }         });      }      @Override     protected void onPreExecute() {         progressDialog.show();     }      @Override     protected void onCancelled() {         running = false;     }      @Override     protected Void doInBackground(Void... params) {          while (running) {             // does the hard work         }         return null;     }      // ...  } 
like image 61
yanchenko Avatar answered Oct 01 '22 04:10

yanchenko


If you're doing computations:

  • You have to check isCancelled() periodically.

If you're doing a HTTP request:

  • Save the instance of your HttpGet or HttpPost somewhere (eg. a public field).
  • After calling cancel, call request.abort(). This will cause IOException be thrown inside your doInBackground.

In my case, I had a connector class which I used in various AsyncTasks. To keep it simple, I added a new abortAllRequests method to that class and called this method directly after calling cancel.

like image 35
wrygiel Avatar answered Oct 01 '22 03:10

wrygiel