I've been using Xamarin's Mono for Android and the MonoCross framework to develop an application, which is currently running under Android (2.3, 4.0 and others). In my app, I have a main activity, from where the user can start new activities, which again start other activities and so on. (e.g. Main -> A -> B -> C)
From time to time, I get following problem: When the application is paused (or stopped) for some time (i.e. not in the foreground), and/or other memory consuming apps are started, and then I return to my app, it isn't restarted correctly. That means, I can see parts of activity C (the window title) for some seconds, then C disappears, B comes and so on with A and Main. After Main disappears, I am back on the home screen. When I again start my app, it launches with the Main activity.
In logcat, I see these entries (I hope I didn't cut too much):
05-15 14:36:39.732 I/ActivityManager( 598): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=de.branchare.adwais2013/branchware.adwais.droid.MainActivity u=0} from pid 1349
...
05-15 14:36:39.792 I/ActivityManager( 598): Start proc de.branchare.adwais2013 for activity de.branchare.adwais2013/branchware.adwais.droid.views.ActivityC: pid=29032 uid=10025 gids={3003, 1015, 1028}
...
05-15 14:36:39.952 I/ActivityThread(29032): Pub de.branchare.adwais2013.mono.MonoRuntimeProvider.__mono_init__: mono.MonoRuntimeProvider
...
05-15 14:36:42.966 I/MonoDroid(29032): at MonoCross.Droid.MXDialogActivityView`1<Branchware.Adwais.ModelContainer`1<Branchware.Adwais.Model.Visit>>.OnCreate (Android.OS.Bundle) <0x00053>
05-15 14:36:42.966 I/MonoDroid(29032): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <0x00057>
05-15 14:36:42.966 I/MonoDroid(29032): at (wrapper dynamic-method) object.15bfff07-188b-4aff-a34f-ab878a2a545f (intptr,intptr,intptr) <0x00043>
05-15 14:36:43.036 E/mono (29032):
05-15 14:36:43.036 E/mono (29032): Unhandled Exception:
05-15 14:36:43.036 E/mono (29032): System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
05-15 14:36:43.036 E/mono (29032): at System.Collections.Generic.Dictionary`2[System.Type,System.Object].get_Item (System.Type key) [0x00000] in <filename unknown>:0
05-15 14:36:43.036 E/mono (29032): at MonoCross.Droid.MXDialogActivityView`1[Branchware.Adwais.ModelContainer`1[Branchware.Adwais.Model.Visit]].OnCreate (Android.OS.Bundle bundle) [0x00000] in <filename unknown>:0
05-15 14:36:43.036 E/mono (29032): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState) [0x00000] in <filename unknown>:0
05-15 14:36:43.036 E/mono (29032): at (wrapper dynamic-method) object:15bfff07-188b-4aff-a34f-ab878a2a545f (intptr,intptr,intptr)
05-15 14:36:43.036 I/mono (29032): [ERROR] FATAL UNHANDLED EXCEPTION: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
05-15 14:36:43.036 I/mono (29032): at System.Collections.Generic.Dictionary`2[System.Type,System.Object].get_Item (System.Type key) [0x00000] in <filename unknown>:0
05-15 14:36:43.036 I/mono (29032): at MonoCross.Droid.MXDialogActivityView`1[Branchware.Adwais.ModelContainer`1[Branchware.Adwais.Model.Visit]].OnCreate (Android.OS.Bundle bundle) [0x00000] in <filename unknown>:0
05-15 14:36:43.036 I/mono (29032): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState) [0x00000] in <filename unknown>:0
05-15 14:36:43.036 I/mono (29032): at (wrapper dynamic-method) object:15bfff07-188b-4aff-a34f-ab878a2a545f (intptr,intptr,intptr)
05-15 14:36:43.136 I/ActivityManager( 598): Recipient 29032
05-15 14:36:43.136 I/ActivityManager( 598): Process de.branchare.adwais2013 (pid 29032) has died.
05-15 14:36:43.136 D/InputManager( 598): setFocusedApplication Exception: java.lang.NullPointerException
...
05-15 14:36:43.136 W/ActivityManager( 598): Force removing ActivityRecord{41cc9df0 de.branchare.adwais2013/branchware.adwais.droid.views.ActivityC}: app died, no saved state
...
05-15 14:36:43.166 I/ActivityManager( 598): Start proc de.branchare.adwais2013 for activity de.branchare.adwais2013/branchware.adwais.droid.views.ActivityB: pid=29052 uid=10025 gids={3003, 1015, 1028}
It seems to me as if
- Android has Destroy()ed my activities while they were paused (which I know is correct behavoir)
- Android then tries to Create() new instances of the activities when the user returns to my app (which is correct, too)
- In the framework's MXDialogActivityView.OnCreate(), MonoCross tries to fetch the model from the MXDroidContainer before calling Render():
// fetch the model before rendering!!!
Model = (T)MXDroidContainer.ViewModels[typeof(T)];
// render the model within the view
Render();
- This is where the KeyNotFoundException is thrown (the method Render() is never called), because the MXDroidContainer does not contain the ViewModels any longer. (Probably this instance was also re-created in the meantime, and therefore does not contain any data.)
I know that Android can (or even must) destroy paused/stopped apps. But it's very annoying to watch my app going back the whole activity stack and then disappearing completely, and having to re-re-start it.
What I would like to achieve is:
a) My app should restart where it stopped (in activity C).
If that's not possible, then
b) My app should restart at the MainLauncher (in activity Main), completely re-initialized.
I've already read (and played around with) a lot about activity lifecycle, launch modes, AlwaysRetainTaskState, ... But I did not yet find a solution to my problem.
Any help or pointers would be greatly appreciated.
TIA, Manfred.