The mentioned in comments case that isCancelled() always returns false even i call asynctask.cancel(true);
is especially harmful if I close my app, but the AsyncTask continues working.
To solve this I modified the proposed by Jacob Nordfalk
code in the following way:
protected Object doInBackground(Object... x) {
while (/* condition */) {
// work...
if (isCancelled() || (FlagCancelled == true)) break;
}
return null;
}
and added the following to the main activity:
@Override
protected void onStop() {
FlagCancelled = true;
super.onStop();
}
As my AsyncTask was a private class of one of views, so getters or setters of the flag were necessary to inform the AsyncTask about the currently actual flag value.
My multiple tests (AVD Android 4.2.2, Api 17) have shown that if an AsyncTask is already executing its doInBackground
, then isCancelled()
reacts in no way (i.e. continues to be false) to any attempts to cancel it, e.g. during mViewGroup.removeAllViews();
or during an OnDestroy
of the MainActivity
, each of which leads to detaching of views
@Override
protected void onDetachedFromWindow() {
mAsyncTask.cancel(false); // and the same result with mAsyncTask.cancel(true);
super.onDetachedFromWindow();
}
If I manage to force stopping the doInBackground()
thanks to the introduced FlagCancelled
, then onPostExecute()
is called, but neither onCancelled()
nor onCancelled(Void result)
(since API level 11) are not invoked. (I have no idea why, cause they should be invoked and onPostExecute()
should not, "Android API doc says:Calling the cancel() method guarantees that onPostExecute(Object) is never invoked." - IdleSun
, answering a similar question).
On the other hand, if the same AsyncTask hadn't started its doInBackground()
before cancelling, then everything is ok, isCancelled()
changes to true and I may check that in
@Override
protected void onCancelled() {
Log.d(TAG, String.format("mAsyncTask - onCancelled: isCancelled = %b, FlagCancelled = %b", this.isCancelled(), FlagCancelled ));
super.onCancelled();
}