源代码 - https://github.com/benhysell/V.FlyoutTest/

问题 - 在混合片段和基本 View 并使用设备上的设置时 - “开发人员选项/不保留事件”如果 OnDestory() 被调用,然后事件被带回 View ,则 View 模型为空。这会导致空引用异常和应用程序崩溃。

说明
我使用 MvvmCross 在 Android 中有一个滑出/汉堡菜单。在应用程序启动时发生以下步骤:

  • HomeViewModel 设置为加载
  • HomeViewModel 加载 HomeView 设置滑出/汉堡菜单
  • 由于 HomeView 从来没有真正显示过,只是管理它调用的片段并显示 EnterTimeViewModel,默认 View ,也是我们真正关心的那个。
  • 在加载 HomeView 结束时,使用 messenger 插件生成一条消息,以“登录”到系统
  • 消息是在 EnterTimeViewModel 中接收到的,通常在这里我们会做一些检查以查看我们是否已登录,但在这种情况下,我们只需使用 LoginViewModel 调用 ShowViewModel 来模拟登录请求并提示用户。
  • LoginViewModel 不是一个片段,只是一个普通的基本 View 。它显示给用户
  • 在发生这种情况时,HomeView 正在从系统中删除,因为我们设置了“开发人员选项/不保留事件”
  • 用户通过点击登录登录系统,在演示中这是一个空操作,它只是关闭 LoginView
  • 然后恢复 HomeView,除了在恢复期间 EnterTimeViewModel 为空...当 EnterTime View 尝试访问 EnterTimeViewModel 时,会命中空引用。

  • 加载和卸载 HomeView 时,关于 MvvmCross 转换的事件序列如下:
  • OnCreate
  • StartActivityForResult
  • OnStart
  • OnResume
  • OnPause
  • OnSaveInstanceState
  • OnStop
  • OnDestroy

  • 登录后显示登录界面
  • OnCreate
  • OnStart
  • 崩溃,空引用异常

  • 感觉像是跳过了几步,导致崩溃。想法?要去的地方?

    作为引用,我基于滑动菜单的项目 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 - 负责尝试保存 ViewModels,最坏的情况是如果片段从内存中卸载,则重新创建它们。

    最佳答案

    从您的代码来看,您似乎在首次创建片段时手动设置了它们的 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
  • 中来做到这一点
  • 阻止默认的 Android 片段重新创建(例如,通过阻止父 bundle 使用其 OnCreate bundle 并使用您自己的再膨胀逻辑)

  • 注意:Activity 不会发生这种行为,因为 MvvmCross 可以重用 Intent 以重新创建 Activity 的 ViewModel。但是对于 Fragment s,应用程序负责创建这些(在其自定义演示器中),因此当前应用程序也必须负责重新创建 ViewModel

    关于android-fragments - MvvmCross Android - 重新加载片段时 ViewModel 的空引用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24145410/

    10-14 17:16
    查看更多