В комментариях упоминается, что isCancelled() always returns false even i call asynctask.cancel(true);
особенно вредно, если я закрываю свое приложение, но AsyncTask продолжает работать.
Для решения этой проблемы я изменил предложенный код Jacob Nordfalk
следующим образом:
protected Object doInBackground(Object... x) {
while (/* condition */) {
// work...
if (isCancelled() || (FlagCancelled == true)) break;
}
return null;
}
и добавил следующее к основному виду деятельности:
@Override
protected void onStop() {
FlagCancelled = true;
super.onStop();
}
Поскольку мой AsyncTask был закрытым классом одного из представлений, поэтому получатели или установщики флага были обязаны сообщитьAsyncTask о текущем значении флага.
Мои множественные тесты (AVD Android 4.2.2, Api 17) показали, что если AsyncTask уже выполняет свой doInBackground
, то isCancelled()
никак не реагирует(т. е. продолжает быть ложным) при любых попытках его отмены, например, во время mViewGroup.removeAllViews();
или во время OnDestroy
из MainActivity
, каждое из которых приводит к отключению представлений
@Override
protected void onDetachedFromWindow() {
mAsyncTask.cancel(false); // and the same result with mAsyncTask.cancel(true);
super.onDetachedFromWindow();
}
Еслиудалось принудительно остановить doInBackground()
благодаря введенному FlagCancelled
, затем вызывается onPostExecute()
, но ни onCancelled()
, ни onCancelled(Void result)
(начиная с уровня API 11) не вызываются.(Я понятия не имею, почему, потому что они должны вызываться, а onPostExecute()
не должен ", - говорит док API API: вызов метода cancel () гарантирует, что onPostExecute (Object) никогда не будет вызываться." - IdleSun
, отвечая на аналогичный вопрос ).
С другой стороны, если тот же AsyncTask не начал свою doInBackground()
до отмены, то все в порядке, isCancelled()
меняется на true, и я могу проверитьчто в
@Override
protected void onCancelled() {
Log.d(TAG, String.format("mAsyncTask - onCancelled: isCancelled = %b, FlagCancelled = %b", this.isCancelled(), FlagCancelled ));
super.onCancelled();
}