When doing an orientation change in the emulator (ADT v17.0.0), or on a device (original Droid), I noticed that the activity will go through more than one create-destroy cycle sometimes. I found this blog post that mentions the problem, but offers no solution.
My app (API 8) currently does a ‘last-chance’ save of user data in onPause, and retrieves that data in onCreate/onStart, which works fine for a single restart, but gets into concurrency issues if the cycles come back-to-back. Specifically if a load starts before a save is complete, the ‘last-chance’ data is lost.
I did read the Faster Screen Orientation Change Android-developer article which mentions transferring an Object via onRetainNonConfigurationInstance/getLastNonConfigurationInstance. I tried using onRetain/getLast… like a flag to tell if the activity is “restarting”, which works, but I still have the main issue of not knowing if/when any existing save/load operations are completed.
Concurrency & thread-management are not my strongest suits, so I’m looking for a solution that does at least one save & load across any number of back-to-back restarts, without memory leaks. Since fast create-destroy cycles could happen for non-orientation reasons, ideas that just involve breaking/handling orientation changes alone aren’t really what I’m after.
Here’s a log file excerpt with some cycles, you can see where the activity gets created-destroyed twice when going from landscape to portrait. Here’s an excerpt of what I’ve got now:
onPause() {
file_manager.saveTemporaryPattern(); // writes to OutputStream on UI thread
}
onStart() {
findViewById (R.id.main_screen).post (new Runnable() {
file_manager.loadTemporaryPattern(); // reads from InputStream on UI thread
});
if (getLastNonConfigurationInstance() != null) {
// DO SOMETHING HERE?
}
}
onRetainNonConfigurationInstance() {
return dummy_object;
}
Managed to solve the concurrency issue by sending the Load/Save calls to a Handler thread linked to the Application context, rather than the Activity context. Had to setup a Load vs Save token in the calls to check for a Save->Load->Save pattern, avoiding the odd behavior of getting an incomplete activity lifecycle on a landscape->portrait orientation change.
It works in development & on test devices, and doesn’t leak the activity context, so we’ll see how it does in the wild.
In YourApp extends Application:
In YourActivity: