源代码 - https://github.com/benhysell/V.FlyoutTest/
问题 - 在混合片段和基本视图并使用设备上的设置时 - “开发者选项/不保留活动”如果调用OnDestory(),则ViewModel为null,然后活动为重新回到视野中。这会导致空引用异常和应用程序崩溃。
描述 我在Android中使用MvvmCross有一个滑出/汉堡菜单。在应用程序启动时,将执行以下步骤:
在EnterTimeViewModel中收到消息,通常在这里我们会进行某种检查,看看我们是否登录,但在这种情况下,我们只需使用LoginViewModel调用ShowViewModel来模拟登录请求和提示用户。
LoginViewModel不是一个版本,只是一个普通的基本视图。它会向用户显示
在加载和卸载HomeView时,关于MvvmCross转换的事件序列如下:
登录后显示登录屏幕
感觉好像跳过了几个步骤,导致崩溃。想法?去看的地方?
作为参考点,我基于滑动菜单的项目https://github.com/jamesmontemagno/Xam.NavDrawer表现出同样的问题。
更新 实现了修复http://benjaminhysell.com/archive/2014/06/mvvmcross-flyoutnavigation-hamburger-menu-sliding-menu-for-android-null-reference-exception-on-fragment-shown-fix/,tldr - 负责尝试保存ViewModel,最坏的情况是重新创建它们,如果片段是从内存中卸载的。
答案 0 :(得分:6)
从您的代码中,您首次创建时看起来像手动设置了片段的ViewModel:
frag.ViewModel = viewModelLocal;
来自https://github.com/benhysell/V.FlyoutTest/blob/master/V.FlyoutTest.Droid/Views/HomeView.cs#L153
当您的托管Activity
由于“不要保留活动”而被拆除然后再次显示时,Android会将片段状态保存在instanceState包中,它会尝试重新创建这些片段 - (我猜)就是当你看到你的NullReferenceException
时。
要解决此问题,您需要:
ViewModel
出现OnCreateView
期间重新创建bundle
。您可以使用序列化/反序列化技术或在OnCreateView方法中移动ViewModel=viewModelLocal
代码而不是在拥有Activity
bundle
使用其OnCreate
bundle
并使用您自己的重新充气逻辑)注意:Activity
不会发生此行为,因为MvvmCross可以在那里重用Intent
,以便为Activity重新创建ViewModel。但是对于Fragment
s,应用程序负责创建这些(在其自定义演示者中),因此目前应用程序也必须负责重新创建ViewModel
。