2

Here's the scenario:

  • Activity "A" creates and executes AsyncTask "T"
  • As "T" is running in the background, the user moves away from "A"
    • Examples of how the user could move away from "A":
      • Pressing "go" and starting an Intent launching Activity "B" (most common in my app)
      • Pressing the "back" button (also fairly common in my app)
      • Rotating the screen, without android:configChanges="orientation|keyboardHidden"
      • etc.
  • "T" has done its work and returns, trying to call function "F" on "A" to update "A"'s UI, but "A" is... "gone"?!

How can I make sure the above does not "bomb"?

Robottinosino
  • 10,384
  • 17
  • 59
  • 97
  • Does the AsyncTask need to finish? You could always cancel it when A's `onPause()` is called. – A--C Dec 19 '12 at 01:50
  • I think cancelling the AsyncTask when moving to a new activity will do the job, but I will let @iagreen answers this. – Lazy Ninja Dec 19 '12 at 01:50
  • Yes, cancelling is a common method, and is acceptable under a lot of circumstances. I was making the assumption you wanted the thread to finish. – iagreen Dec 19 '12 at 01:55

2 Answers2

1

A very common hurdle in Android development. When I first stumbled on this issue, I found this Q with a lot of great discussion that illuminated things for me:

Is AsyncTask really conceptually flawed or am I just missing something?

It is imperative on you, the author of the AsyncTask, to ensure that it's orphaned completion is 'safe' or else to cancel/abort. The conventional wisdom is to cancel (or at least logically dissociate via some mechanism of your own rolling, as @iagreen proposes) the Task instance from within your Activity's onPause or onDestroy.

Ideal way to cancel an executing AsyncTask

There is frequent guidance around the web from Android team members that AsyncTask is intended to be for short operations whose lifecycle closely matches the 'intended' lifecycle of its parent activity, so if you find yourself doing longrunning operations and having to resume partial progress, etc you might want to look at explicit thread management or coding up a Service, etc:

http://developer.android.com/reference/android/app/Service.html

Community
  • 1
  • 1
Mike Repass
  • 6,825
  • 5
  • 38
  • 35
  • Also, this is a very important/relevant comment from a member of the Android team on the behavior of cancel/isCancelled() http://stackoverflow.com/questions/2531336/asynctask-wont-stop-even-when-the-activity-has-destroyed?rq=1#comment2531187_2531485 – Mike Repass Dec 19 '12 at 02:14
1

The main problem is that 'AsyncTask's are usually defined as non-static inner classes of an Activity. That means it holds a reference to the Activity. If your Activity is destroyed or destroyed and recreated for whatever reason, your AsyncTask is still referencing to your 'old' Activity. Since that activity is no longer attached to the UI, if you try to modify and UI components, you get an exception.

One option, is to set the status of the Activity in onStop() -- have a boolean variable indicate whether if the process was stopped. Check that before updating the UI.

iagreen
  • 31,470
  • 8
  • 76
  • 90
  • In the interest of full disclaimer, I got fed up with `AsyncTask`s about a year ago after messing with these exact problems and switched to a handling background tasks with `Thread` and `Handlers` directly. – iagreen Dec 19 '12 at 01:59