1

PrintStatusTask parses the contents of a gmail inbox looking for various items of interest to report on. But a new AsyncTask is created for each PrintStatusTask().execute() according to the debugger. Shouldn't these tasks die on exit? Do they have to be killed manually?

public class Controller extends Activity {
    ...
    private boolean applyMenuChoice(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menuStatus:
            new PrintStatusTask().execute();
            ...
    class PrintStatusTask extends AsyncTask<Void, String, Void> {
        @Override
        protected Void doInBackground(Void... unused) {
            ...
            return null;
        }
        @Override
        protected void onPostExecute(Void unused) {
            this.cancel(true);
        }   
    }
}
jacknad
  • 13,483
  • 40
  • 124
  • 194

2 Answers2

5

Ok guys I'm sorry but I have to tell you you are wrong. An AsyncTask is (almost) NEVER killed. Calling AsyncTask.cancel will NOT kill the task.

Quoted From the documentation of AsyncTask

A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)

reading docs can be useful... So i'll sum it up for you, but since I already answered in another post, I send you to it : How can I make asynchronous URL connections on Android?

I gave a workaround to your problem, and yes, some time, some AsyncTask are killed. But I won't recommend using them, they're useless. But since, your AsyncTasks running should show a "waiting" status if they're done with the task. Otherwise your task is NOT done, and I never heard about some adb thread watching bug.

Regards !

Community
  • 1
  • 1
Nabil Gardon
  • 175
  • 1
  • 1
  • Hi, maybe the link you provided is wrong, since I can't see an answer of yours in the post you linked. Anyway.... could callling `isCancelled()` inside the `doInBackground()` method solve the problem? – ocramot Apr 19 '15 at 12:38
1

If you keep a reference to the task around, you can call its cancel method to cancel it. Otherwise, they live as long as your app's process does, or until they return from the doInBackground and (if present) onPostExecute functions.

Walter Mundt
  • 24,753
  • 5
  • 53
  • 61
  • PrintStatusTask does exit after the task completes. But adding this.cancel(true) to onPostExecute() in PrintStatusTask (see updated snippet) also does not kill the task. I suppose the task will go away after it drains the battery and the device is off, but don't like that workaround. Any other ideas? – jacknad Aug 17 '10 at 23:01
  • 1
    Calling `cancel` in `onPostExecute` is useless, because that only gets called after the task completes or is canceled. You have to call it elsewhere. For example, if you add an `AsyncTask` field to your `Activity` and save the task there when you create it, you can later do `mPrintTask.cancel` on your activity's `onDestroy`, if that's appropriate. You have to choose the lifecycle of your task before you can find an appropriate place to cancel it, of course. – Walter Mundt Aug 18 '10 at 00:55
  • That is what I thought. Except that onPostExecute does get called, but the AsyncTask is still shown as running in the debug window. Is this possibly a defect in the Eclipse/Android environment that does not properly remove the AsyncTask indication from the debug window, even though the task has actually exited? – jacknad Aug 18 '10 at 11:18