我一直在使用 Xamarin 的 Mono for Android 和 MonoCross 框架来开发一个应用程序,该应用程序目前在 Android(2.3、4.0 和其他)下运行。在我的应用程序中,我有一个主要活动,用户可以从那里开始新活动,然后再次开始其他活动等等。(例如主 -> A -> B -> C)
有时,我会遇到以下问题:当应用程序暂停(或停止)一段时间(即不在前台),和/或启动其他消耗内存的应用程序,然后我返回我的应用程序时,它是'没有正确重新启动。这意味着,我可以看到部分活动 C(窗口标题)几秒钟,然后 C 消失,B 出现,以此类推,A 和 Main。Main 消失后,我又回到了主屏幕。当我再次启动我的应用程序时,它会与 Main 活动一起启动。
在 logcat 中,我看到了这些条目(我希望我没有删减太多):
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}
在我看来,好像
- Android 在暂停时破坏了我的活动(我知道这是正确的行为)
- Android 然后在用户返回我的应用程序时尝试 Create() 活动的新实例(这是也正确)
- 在框架的 MXDialogActivityView.OnCreate() 中,MonoCross 在调用 Render() 之前尝试从 MXDroidContainer 获取模型:
// fetch the model before rendering!!!
Model = (T)MXDroidContainer.ViewModels[typeof(T)];
// render the model within the view
Render();
- 这是引发 KeyNotFoundException 的地方(永远不会调用 Render() 方法),因为 MXDroidContainer 不再包含 ViewModel。(可能同时此实例也被重新创建,因此不包含任何数据。)
我知道 Android 可以(甚至必须)销毁暂停/停止的应用程序。但是看着我的应用程序返回整个活动堆栈然后完全消失,并且不得不重新启动它是非常烦人的。
我想要实现的是:
a)我的应用程序应该在它停止的地方重新启动(在活动 C 中)。
如果这不可能,那么
b) 我的应用程序应该在 MainLauncher 重新启动(在 Main 活动中),完全重新初始化。
我已经阅读(并玩过)很多关于活动生命周期、启动模式、AlwaysRetainTaskState 的内容……但我还没有找到解决问题的方法。
任何帮助或指示将不胜感激。
TIA,曼弗雷德。