DialogFragment / FragmentManager在轮换时崩溃(使用MVVMCross):IllegalStateException:在onSaveInstanceState之后无法执行此操作

时间:2015-07-09 15:01:46

标签: android mvvmcross android-support-library android-dialogfragment fragmentmanager

我见过其他人遇到类似的问题,但我的情况有点不同。我不确定它是否是MVVMCross问题,或者Androind.Support.V4库是否有问题。我正在使用Xamarin Studio。

我有一个管理FragmentDialog的活动。

在我的OnCreate方法中,我检查是否显示现有的DialogFragment。这适用于已打开DialogFragment并发生旋转的情况。在每个OnCreate上,我使用我指定的标签查找对话框。 MVVMCross使用支持库作为其MXVFragmentAcitivity的一部分。我使用实现getter的属性SupportFragmenetManager获取FragmentManager(我相信私有的setter)。

第一次创建活动时,一切都按预期工作。已打开的对话框不会导致任何问题,因为它在OnCreate方法中处理。

我做的第一件事是base.OnCreate(捆绑)。

当我旋转屏幕然后尝试调用我的对话框时会出现问题。

根据我的调试和跟踪,当旋转发生时,OnDetroy会按预期调用。我查看了SupportFragmentManager的状态。此时它被标记为被毁坏。

当使用OnCreate创建新活动时,我检查SupportFragmentManager并且我看到有一个新实例。有道理。

我通过OnViewModelSet和OnResume跟踪它,一切都很好。

一旦设置了视图,我点击我想要的按钮来调用对话框。第一次调用对话框的步骤相同。

app崩溃于dialog.show(SupportFragmentManager,dialogName);

我可以看到正在调用旧的SupportFragmentManager。它没有任何意义。我认为活动正在以某种方式重新加载旧的FragmentManger。它是否可能存储在捆绑包中并在某一点恢复。基于Android文档OnRestoreInstance发生在OnResume之前。如前所述,当我在OnResume中检查SupportFragmentManager时,它有一个新值。

我有点困惑。收到的异常是:java.lang.IllegalStateException:onSaveInstanceState之后无法执行此操作

这是我的代码的简短版本:

活动OnCreate:

protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
            SetContentView (Resource.Layout.session_page_layout);
            Window.AddFlags (WindowManagerFlags.KeepScreenOn);

            var existingDialog = (ConnectionDialogFragment)SupportFragmentManager.FindFragmentByTag(BLEDialogTagName);
            if (existingDialog != null)
                existingDialog.ViewModel = Mvx.GetSingleton<IDeviceList>() as DeviceListVM;//Mvx.IocConstruct<DeviceListVM> ();
        }

FragmentDialog OnCreateDialog:

public override Dialog OnCreateDialog(Bundle savedState)
        {
            base.EnsureBindingContextSet(savedState);
            var view = this.BindingInflate(Resource.Layout.DeviceListView, null);
            var dialog = new AlertDialog.Builder(Activity);
            dialog.SetTitle(title);
            dialog.SetView(view);
            dialog.SetNeutralButton("Close", (s, a) => { Dismiss();});
            return dialog.Create();
        }

和来自Activity的调用:

private void ShowDeviceDialog()
        {
            var dialog = new ConnectionDialogFragment ();
            //Removed ViewModel setting as it is irrelavent
            dialog.Show (SupportFragmentManager, BLEDialogTagName);  
        }

如果有人能够对这个问题有所了解,我感激不尽。我已经看到类似的问题,但似乎这些与对话框启动时的旋转和应用程序崩溃有关。同样,当对话框启动并发生旋转时,我不会崩溃。在OnCreate中,SupportFragmentManager的状态良好且正确。临时修复是将屏幕锁定到方向。我将它锁定到肖像,直到我能找出问题。

1 个答案:

答案 0 :(得分:2)

经过进一步调查,我发现我在OnCreate注册了一个活动,当活动被销毁时我没有注销。因此,事件处理程序仍然会将消息发送到被销毁的旧活动。在OnDestroy中添加此解决了此异常。我在Android 5上测试了这个。