Ideal way to cancel an executing AsyncTask

前端 未结 9 2108
不思量自难忘°
不思量自难忘° 2020-11-22 05:54

I am running remote audio-file-fetching and audio file playback operations in a background thread using AsyncTask. A Cancellable progress bar is sh

9条回答
  •  一向
    一向 (楼主)
    2020-11-22 06:38

    With reference to Yanchenko's answer on 29 April '10: Using a 'while(running)' approach is neat when your code under 'doInBackground' has to be executed multiple times during every execution of the AsyncTask. If your code under 'doInBackground' has to be executed only once per execution of the AsyncTask, wrapping all your code under 'doInBackground' in a 'while(running)' loop will not stop the background code (background thread) from running when the AsyncTask itself is cancelled, because the 'while(running)' condition will only be evaluated once all the code inside the while loop has been executed at least once. You should thus either (a.) break up your code under 'doInBackground' into multiple 'while(running)' blocks or (b.) perform numerous 'isCancelled' checks throughout your 'doInBackground' code, as explained under "Cancelling a task" at https://developer.android.com/reference/android/os/AsyncTask.html.

    For option (a.) one can thus modify Yanchenko's answer as follows:

    public class MyTask extends AsyncTask {
    
    private volatile boolean running = true;
    
    //...
    
    @Override
    protected void onCancelled() {
        running = false;
    }
    
    @Override
    protected Void doInBackground(Void... params) {
    
        // does the hard work
    
        while (running) {
            // part 1 of the hard work
        }
    
        while (running) {
            // part 2 of the hard work
        }
    
        // ...
    
        while (running) {
            // part x of the hard work
        }
        return null;
    }
    
    // ...
    

    For option (b.) your code in 'doInBackground' will look something like this:

    public class MyTask extends AsyncTask {
    
    //...
    
    @Override
    protected Void doInBackground(Void... params) {
    
        // part 1 of the hard work
        // ...
        if (isCancelled()) {return null;}
    
        // part 2 of the hard work
        // ...
        if (isCancelled()) {return null;}
    
        // ...
    
        // part x of the hard work
        // ...
        if (isCancelled()) {return null;}
    }
    
    // ...
    

提交回复
热议问题