1

First, a short description of the problem's background:

I've run into troubles with handling background workers lifecycles in line with Activity lifecycle. First problem is that a new instance of activity is created whenever the configuration changes (this includes screen orientation) so I had to pull my workers from the old instance to the new one. Second, this is complicated by the fact that sometimes workers display a progress dialog and also, occasionally, they display an error dialog which the user has to interact with. Handling all that stuff - workers, dialogs, etc. - across the activity instances has grown so complex that now I clearly see it was the wrong way to go.

The right way to go, I believe, was to eliminate that re-instantiation in the first place. If that was provided then I had activities with a very straight-forward and simple lifecycle and no need for tracking workers and dialogs. This can be achieved by putting android:configChanges="..." in the manifest.

Now, the question is:

Given that activity has android:configChanges="..." which includes every possible thing (orientation, keyboard, and all the rest) - is there a guarantee that an activity is instantiated exactly once while it's alive and not killed/re-created even in the background? The documentation is not clear about this point.

If someone knows cases when such guarantee doesn't hold up - please let me know. And most important - how to simulate those cases in order to test against them?

I appreciate your answers very much.

PS: What documentation does say is that "system can remove your activity at any point if it wants to" - but we don't consider it here, because that will be a new story for a new instance when the user is back to the screen which activity got removed this way. In this case we'll simply start from the scratch like if the user just opened this screen.

JBM
  • 2,930
  • 2
  • 24
  • 28
  • "The right way to go, I believe, was to eliminate that re-instantiation in the first place." -- probably not. Get rid of the dialog boxes. Use `onRetainNonConfigurationInstance()` for passing `AsyncTask` objects and the like between activity instances being destroyed/recreated due to configuration changes, or have such "workers" in fragments with via `setRetainInstance()`. – CommonsWare May 31 '11 at 18:23
  • @CommonsWare - Thanks for your answer! I already use `onRetainNonConfigurationInstance()` to pass the workers, but it's not that easy with dialogs, unfortunately. The dialog is created by the worker and the Activity only shows it; it doesn't know how to create a copy of that dialog when it needs to show it in the new instance. Or what did you mean saying "get rid of dialog boxes"? – JBM May 31 '11 at 21:10
  • I meant "get rid of dialog boxes". As in "don't have them", "nuke them from orbit", and "Reto doesn't like them, either" -- http://blog.radioactiveyak.com/2010/08/what-you-can-do-with-your-modal-dialogs.html – CommonsWare May 31 '11 at 21:29

2 Answers2

1

If you are asking this, your app is probably broken.

So -- why do you care? If you can't handle your activity being restarted, then you will break in the situation where your app's process needs to be killed for memory while in the background and the user later returns to it.

If you can handle being restarted, why do you care that there may be some case where the activity needs to be restarted?

Anyway the answer is that there is no way to guarantee that the activity is never restarted, so don't abuse android:configChanges to try to avoid that. You can't prevent it, you just make it less obvious to yourself that your app is broken, but users will still encounter the bugs you have.

If you are having trouble dealing with this, consider using some recent facilities like fragments and loaders in the new support library. These have a number of features that make it easier for apps to handle their activity being restarted -- fragments can be retained across restarts, loaders keep their data loads active, etc.

Also the set of possible reasons that an app may need to be restarted is not fixed. New changes can and will be added in the future, and you can't account for them.

hackbod
  • 90,665
  • 16
  • 140
  • 154
  • `the situation where your app's process needs to be killed for memory while in the background and the user later returns to it` - I'd appreciate very much if you tell me **how** the user can return to a killed process without having it started from scratch? – JBM May 31 '11 at 16:53
  • I've looked into Loaders and it's said that they handle configuration change automatically - very nice, but there is one problem: Loaders are available since API 11 and I have to support APIs 3+. Is there a way to achieve the same using API 3 facilities? I appreciate your answer very much. – JBM May 31 '11 at 17:08
  • @JBM: Loaders are in the Android Compatibility Library. – CommonsWare May 31 '11 at 18:20
0

Usually, when you want some objects to remain accross activity recreation, you should make them depend, not on the activity, but on the application context. If your application object, as recommended, is a singleton, then it would be much easier to make your items survive to the activity life cycle.

Here is an exemple on how to do that : How to declare global variables in Android?

Community
  • 1
  • 1
Snicolas
  • 37,840
  • 15
  • 114
  • 173
  • And for dialogs, I don't know exactly how they can be handled, I am looking for more information from other members on this thread. – Snicolas May 31 '11 at 16:34