[android-developers] Should AsyncTask.cancel(true) work?

1921 views
Skip to first unread message

Nathan

unread,
Apr 20, 2010, 4:42:49 PM4/20/10
to Android Developers
Cause it doesn't.

I have a service running an Asynctask to do some work.

I bind to it from an activity and call a cancel method. The service,
in turn, calls AsyncTask.cancel(true);

AyncTask.cancel returns true. Nonetheless, the thread is still running
happily and still doing the things in doInBackGround, sending
notifications along the way.

There is no sign that it attempted to kill the thread.

I am not using NDK calls or anything that I think should stop if from
taking down the thread.

What am I doing wrong? Or is this a known issue?

Nathan

public final boolean cancel (boolean mayInterruptIfRunning)

Since: API Level 3
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, already been cancelled, or could not
be cancelled for some other reason. If successful, and this task has
not started when cancel is called, this task should never run. If the
task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
Parameters
mayInterruptIfRunning true if the thread executing this task should be
interrupted; otherwise, in-progress tasks are allowed to complete.
Returns
false if the task could not be cancelled, typically because it has
already completed normally; true otherwise

--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-d...@googlegroups.com
To unsubscribe from this group, send email to
android-develop...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Nathan

unread,
Apr 20, 2010, 5:04:39 PM4/20/10
to Android Developers
Because it isn't.

AsynTask.cancel(true) is called from a service on its AsyncTask

It returns true.

After the call, AsyncTask.iscancelled() is true.

Nonetheless, the thread is still running happily and performing the
tasks in doinBackground as if nothing had happened. I can see this all
in the debugger.

Any ideas? Is this a known issue?

I see no evidence that this is working according to its documentation,
below.

Dianne Hackborn

unread,
Apr 20, 2010, 5:11:29 PM4/20/10
to android-d...@googlegroups.com
Killing threads is horribly bad and not something anyone should do.  You need to check in your task if it has been canceled, and return if so.
--
Dianne Hackborn
Android framework engineer
hac...@android.com

Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails.  All such questions should be posted on public forums, where I and others can see and answer them.

Nathan

unread,
Apr 20, 2010, 6:16:35 PM4/20/10
to Android Developers
On Apr 20, 2:11 pm, Dianne Hackborn <hack...@android.com> wrote:
> Killing threads is horribly bad and not something anyone should do.  You
> need to check in your task if it has been canceled, and return if so.
>

I don't necessarily disagree. But that is what the documentation says
it does. So someone who wrote the documentation thought killing
threads was fine and the person who implemented it thought differently
and ignored the parameter? They should probably talk.

When Android kills the service, which it can do at any time without
warning, does it kill the Async threads? I'm assuming so. So it
sounds like I do have to handle thread death whether I initiate it or
not.

Nathan

Mark Murphy

unread,
Apr 20, 2010, 6:24:48 PM4/20/10
to android-d...@googlegroups.com
Nathan wrote:
> On Apr 20, 2:11 pm, Dianne Hackborn <hack...@android.com> wrote:
>> Killing threads is horribly bad and not something anyone should do. You
>> need to check in your task if it has been canceled, and return if so.
>>
>
> I don't necessarily disagree. But that is what the documentation says
> it does. So someone who wrote the documentation thought killing
> threads was fine and the person who implemented it thought differently
> and ignored the parameter? They should probably talk.

I am fairly certain the person who wrote the documentation and who wrote
the class is the same person, and I'm not aware that he suffers from
multiple personality disorder. :-)

The documentation, as you quoted earlier, says:

"If the task has already started, then the mayInterruptIfRunning
parameter determines whether the thread executing this task should be
interrupted in an attempt to stop the task."

That does not imply, however, that the thread is interruptible. That's a
Java thing, not an AsyncTask thing.

I'm with Ms. Hackborn on this one -- I avoid designs that require Java
threads to be stopped.

> When Android kills the service, which it can do at any time without
> warning, does it kill the Async threads?

If by "kills the service" you mean "destroys the service", then no, I'm
reasonably certain the threads are not killed. The AsyncTask will run to
completion regardless of the status of the component that started is.
Leastways, I'm rather sure this is what happens with activities, and I'm
not aware of any differences with respect to services in this regard.
AsyncTask maintains a thread pool, so even when the task is complete,
the thread does not necessarily terminate.

If by "kills the service" you mean "terminates the process", then yes,
the thread will go away when the process goes away.

--
Mark Murphy (a Commons Guy)
http://commonsware.com | http://twitter.com/commonsguy

Android Training...At Your Office: http://commonsware.com/training

abisai rangel

unread,
Apr 20, 2010, 6:50:39 PM4/20/10
to android-d...@googlegroups.com
New HP Slate Photos here ----> Website with photos

Nathan

unread,
Apr 20, 2010, 7:10:48 PM4/20/10
to Android Developers
On Apr 20, 3:24 pm, Mark Murphy <mmur...@commonsware.com> wrote:
> That does not imply, however, that the thread is interruptible. That's a
> Java thing, not an AsyncTask thing.
>

OK, that's what I needed to check on. The task is doing IO so it
should get interrupted eventually, but I could be catching it as an
IOException and continuing.

At any rate, the graceful cancellation works.


> I'm with Ms. Hackborn on this one -- I avoid designs that require Java
> threads to be stopped.
>
> > When Android kills the service, which it can do at any time without
> > warning, does it kill the Async threads?
>

> If by "kills the service" you mean "destroys the service", then no, I'm
> reasonably certain the threads are not killed. The AsyncTask will run to
> completion regardless of the status of the component that started is.
> Leastways, I'm rather sure this is what happens with activities, and I'm
> not aware of any differences with respect to services in this regard.
> AsyncTask maintains a thread pool, so even when the task is complete,
> the thread does not necessarily terminate.
>
OK, now I'm worried. I see a possible runaway task here with no way to
cancel.

I should of course call AsyncTask.cancel() in onDestroy()

But Ms. Hackborn has stated in previous threads that onDestroy() won't
necessarily be called when a service is destroyed.

> If by "kills the service" you mean "terminates the process", then yes,
> the thread will go away when the process goes away.
>
If the process is alway terminated when a service is destroyed without
warning, then I won't worry about the runaway task.

Nathan

Dianne Hackborn

unread,
Apr 20, 2010, 7:20:17 PM4/20/10
to android-d...@googlegroups.com
On Tue, Apr 20, 2010 at 4:10 PM, Nathan <nathan....@gmail.com> wrote:
> If by "kills the service" you mean "destroys the service", then no, I'm
> reasonably certain the threads are not killed. The AsyncTask will run to
> completion regardless of the status of the component that started is.
> Leastways, I'm rather sure this is what happens with activities, and I'm
> not aware of any differences with respect to services in this regard.
> AsyncTask maintains a thread pool, so even when the task is complete,
> the thread does not necessarily terminate.
>
OK, now I'm worried. I see a possible runaway task here with no way to
cancel.

I should of course call AsyncTask.cancel() in onDestroy()

But Ms. Hackborn has stated in previous threads that onDestroy() won't
necessarily be called when a service is destroyed.

onDestroy() won't be called only in the case where your entirely process is killed to free up memory.

--
Dianne Hackborn
Android framework engineer
hac...@android.com

Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails.  All such questions should be posted on public forums, where I and others can see and answer them.

Nathan

unread,
Apr 20, 2010, 7:28:08 PM4/20/10
to Android Developers
On Apr 20, 4:20 pm, Dianne Hackborn <hack...@android.com> wrote:
>
> onDestroy() won't be called only in the case where your entirely process is
> killed to free up memory.
>

OK, no worry about runaway threads then. But I will be watching the
memory.

Nathan

Håvard Christensen

unread,
Apr 17, 2012, 5:06:05 PM4/17/12
to android-d...@googlegroups.com
Updating the documentation to clearify the fact that it works like this, would be a very good thing.
I haven't run into this issue myself, but the more clearification there is in documentation, the better. Makes all devs happy.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to

Håvard Christensen

unread,
Apr 17, 2012, 5:26:36 PM4/17/12
to android-d...@googlegroups.com
I still think the documentation could be clearer.


On Tuesday, April 20, 2010 10:42:49 PM UTC+2, Nathan wrote:

Romain Guy

unread,
Apr 22, 2012, 10:45:17 PM4/22/12
to android-d...@googlegroups.com
If doInBackground() is already running, cancel can only stop the
operation if your implementation periodically check for isCancelled().
For instance:

for (int i = 0; i < count; i++) {
if (isCancelled()) break;
doStuff(i);
}

In addition, the parameter passed to cancel can be used to interrupt
interruptible operations (I/O for instance.) I agree the documentation
should be clearer though.

> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-d...@googlegroups.com
> To unsubscribe from this group, send email to
> android-develop...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en

--
Romain Guy
Android framework engineer
roma...@android.com

Reply all
Reply to author
Forward
0 new messages