重新启动应用程序时,MXDialogActivityView.OnCreate()中的MonoCross:KeyNotFoundException [英] MonoCross: KeyNotFoundException in MXDialogActivityView.OnCreate() when re-starting application

查看:80
本文介绍了重新启动应用程序时,MXDialogActivityView.OnCreate()中的MonoCross:KeyNotFoundException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用Xamarin的Android版Mono和MonoCross框架来开发应用程序,该应用程序目前在Android(2.3、4.0和其他版本)下运行. 在我的应用程序中,我有一个主要活动,用户可以从中开始新活动,然后再开始其他活动,依此类推. (例如Main-> A-> B-> C)

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)

我有时会遇到以下问题: 当应用程序暂停(或停止)一段时间(即不在前台),和/或启动了其他消耗内存的应用程序,然后又返回到我的应用程序时,它无法正确重启. 这意味着,我可以看到活动C的一部分(窗口标题)几秒钟,然后C消失,B出现,以此类推,A和Main依此类推. Main消失后,我回到主屏幕.当我再次启动我的应用程序时,它将以Main活动启动.

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.

在logcat中,我看到了这些条目(我希望不要减少太多):

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}

在我看来,好像是
-暂停时,Android已销毁了我的活动(我知道这是正确的行为)
-然后,当用户返回我的应用程序时,Android也会尝试创建()活动的新实例(也是正确的)
-在框架的MXDialogActivityView.OnCreate()中,MonoCross尝试在调用Render()之前从MXDroidContainer中获取模型:

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();  

-这是抛出KeyNotFoundException的地方(从不调用Render()方法),因为MXDroidContainer不再包含ViewModels. (可能与此同时也重新创​​建了该实例,因此它不包含任何数据.)

- 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.)

我知道Android可以(甚至必须)销毁已暂停/已停止的应用程序. 但是看到我的应用程序返回整个活动堆栈然后完全消失,然后不得不重新启动它,这真是令人讨厌.

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.

我想实现的是:
a)我的应用应在停止的位置(在活动C中)重新启动.
如果那不可能,那么
b)我的应用程序应在MainLauncher(活动Main)中重新启动,并完全重新初始化.

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.

我已经阅读(并玩过)很多有关活动生命周期,启动模式,AlwaysRetainTaskState等的内容. 但是我还没有找到解决问题的方法.

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, 曼弗雷德.

TIA, Manfred.

推荐答案

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

I think your analysis of the Activity lifecycle and its interaction with the MonoCross framework is correct.

我不确定MonoCross目前是否对这种墓碑化"有任何处理-因此,如果您要处理此问题,则需要自己进行.

I'm not sure if MonoCross has any handling currently for this kind of 'tombstoning' - so if you want to handle this, then you'll need to do do so yourself.

为此,您需要:

  • 使用protected override void OnSaveInstanceState(Bundle outState)方法将视图的当前任何模型数据保存/序列化到捆绑包中
  • 覆盖默认的MX*ActivityView.OnCreate行为,以便使用bundle参数,该参数将包含已保存的实例状态.
  • use the protected override void OnSaveInstanceState(Bundle outState) method to save/serialise any current Model data for your View into the Bundle
  • override the default MX*ActivityView.OnCreate behaviour in order to use the bundle parameter which will contain the saved instance state.

我最近在MvvmCross中完成了相同类型的操作.但是,模型的生命周期在MvvmCross中是非常不同的-我相信MonoCross总是在内存中保留每个模型的一个实例,而MvvmCross只是将每个View链接到其ViewModel-因此ViewModel生命周期与View生命周期紧密相关.因此,我担心Mvx代码可能无法轻松地移植回MX ...

I've done this same type of thing recently within MvvmCross. However, the lifecycle of models is very different in MvvmCross - I believe MonoCross always keeps exactly one instance of each model in memory, whereas MvvmCross just links each View to its ViewModel - so the ViewModel lifecyle is tied precisely to the View lifecyle. Because of this I'm afraid that Mvx code may not port easily back to MX...

这篇关于重新启动应用程序时,MXDialogActivityView.OnCreate()中的MonoCross:KeyNotFoundException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆