В соответствии с этим вы должны периодически проверять isCancelled () в doInBackground, потому что mytask.cancel (true) не будет прерывать doInBackground самостоятельно.
На самом деле это не так.
Согласно документации :
После вызова этого метода необходимо периодически проверять значение, возвращаемое isCancelled () из doInBackground (Object []), чтобы завершитьзадание как можно раньше.
Это означает, что вы можете дополнительно проверить, чтобы isCancelled()
остановить AsyncTask
раньше , если оно запущено.
mytask.cancel (true) все равно прекратит выполнение.
Давайте посмотрим, что происходит под капотом
Когда вы звоните mytask.cancel(true)
:
public final boolean cancel(boolean mayInterruptIfRunning) {
mCancelled.set(true);
return mFuture.cancel(mayInterruptIfRunning);
}
Где mFuture
- это FutureTask
, который поддерживает работоспособность внутри
Затем вызывается mFuture.cancel
:
public boolean cancel(boolean mayInterruptIfRunning) {
if (state != NEW)
return false;
if (mayInterruptIfRunning) {
if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))
return false;
Thread t = runner;
if (t != null)
t.interrupt();
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state
}
else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))
return false;
finishCompletion();
return true;
}
Где runner
это просто
private volatile Thread runner;
Поскольку это просто поток, давайте посмотрим, что interrupt
делает в вашем случае:
Если этот поток заблокирован вОперация ввода / вывода для прерываемого канала, после чего канал будет закрыт, состояние прерывания потока будет установлено, и поток получит исключение ClosedByInterruptException.
Так что если ваш download()
метод использует InterruptibleChannel
interrupt
будет работать.
Другими словами, похоже, что вам никогда не приходилось вызывать isCancelled()
для прерывания AsyncTask
=), поскольку Thread.interrupt
может прекратить блокировку io в вашем случае.