1

我一直在使用 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,曼弗雷德。

4

1 回答 1

1

我认为您对 Activity 生命周期及其与 MonoCross 框架交互的分析是正确的。

我不确定 MonoCross 目前是否对这种“墓碑”有任何处理——所以如果你想处理这个,那么你需要自己做。

为此,您需要:

  • 使用该protected override void OnSaveInstanceState(Bundle outState)方法将视图的任何当前模型数据保存/序列化到包中
  • 覆盖默认MX*ActivityView.OnCreate行为以使用bundle将包含已保存实例状态的参数。

我最近在 MvvmCross 中做了同样的事情。然而,模型的生命周期在 MvvmCross 中是非常不同的——我相信 MonoCross 总是在内存中保留每个模型的一个实例,而 MvvmCross 只是将每个视图链接到它的视图模型——所以视图模型生命周期与视图生命周期精确相关。正因为如此,我担心 Mvx 代码可能不容易移植回 MX ......

于 2013-05-18T11:49:25.883 回答