Со ссылкой на ответ Янченко от 29 апреля 2010 года:
Подход 'while (running)' изящен, когда ваш код в doInBackground должен выполняться несколько раз во время каждого выполнения AsyncTask. Если ваш код в «doInBackground» должен выполняться только один раз за выполнение AsyncTask, завершение всего вашего кода в «doInBackground» в цикле «while (выполняется)» не остановит выполнение фонового кода (фонового потока), когда Сам AsyncTask отменяется, потому что условие while (выполняется) будет оцениваться только после того, как весь код цикла while будет выполнен хотя бы один раз. Таким образом, вы должны либо
(а.) разбить ваш код в doInBackground на несколько блоков «в то время как (работает)» или
(б) выполнить многочисленные проверки isCancelled в коде doInBackground, как описано в разделе «Отмена задачи» на https://developer.android.com/reference/android/os/AsyncTask.html.
Для варианта (а) можно изменить ответ Янченко следующим образом:
public class MyTask extends AsyncTask<Void, Void, Void> {
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;
}
// ...
Для опции (b.) Ваш код в doInBackground будет выглядеть примерно так:
public class MyTask extends AsyncTask<Void, Void, Void> {
//...
@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;}
}
// ...