Сбой DialogFragment/FragmentManager при вращении (с использованием MVVMCross): IllegalStateException: невозможно выполнить это действие после onSaveInstanceState

Я видел, как другие люди сталкиваются с подобной проблемой, но мой случай немного отличается. Я не уверен, что это проблема MVVMCross или что-то не так с библиотекой Androind.Support.V4. Я использую Xamarin Studio.

У меня есть действие, которое управляет FragmentDialog.

В моем методе OnCreate я проверяю, отображается ли существующий DialogFragment. Это для случая, когда DialogFragment уже открыт и происходит вращение. В каждом OnCreate я ищу диалог, используя назначенный тег. MVVMCross использует библиотеку поддержки как часть своей MXVFragmentAcitivity. Я получаю FragmentManager, используя свойство SupportFragmenetManager, которое реализует геттер (я полагаю, частные сеттеры).

При первом создании активности все работает как надо. Уже открытое диалоговое окно не вызовет никаких проблем, так как об этом позаботится метод OnCreate.

Первое, что я делаю, это base.OnCreate(bundle).

Проблема возникает, когда я поворачиваю экран, а затем пытаюсь вызвать диалоговое окно.

Основываясь на моей отладке и отслеживании, когда происходит ротация, OnDetroy вызывается, как и ожидалось. Я проверил состояние SupportFragmentManager. В этот момент он помечен как уничтоженный.

Когда новое действие создается с помощью OnCreate, я проверяю SupportFragmentManager и вижу, что есть новый экземпляр. Имеет смысл.

Я отследил это через OnViewModelSet и OnResume, и все в порядке.

Как только представление настроено, я нажимаю нужную кнопку, чтобы вызвать диалоговое окно. Те же шаги для вызова диалогового окна в первый раз.

Приложение аварийно завершает работу в dialog.show(SupportFragmentManager, dialogName);

Я вижу, что вызывается старый SupportFragmentManager. Это не имеет смысла. Я думаю, что активность каким-то образом перезагружает старый FragmentManger. Возможно ли, что он хранится в комплекте и восстанавливается в один момент. На основе документации Android OnRestoreInstance происходит до OnResume. Как упоминалось ранее, когда я проверяю SupportFragmentManager в OnResume, у него появляется новое значение.

Я немного смущен. Получено следующее исключение: java.lang.IllegalStateException: невозможно выполнить это действие после onSaveInstanceState

Вот короткая версия кода, который у меня есть:

Активность при создании:

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

Фрагментдиалог 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);  
        }

Я ценю, если кто-то может пролить свет на этот вопрос. Я видел похожую проблему, но, похоже, она связана с вращением и сбоями приложения, когда диалоговое окно открыто. Опять же, я не получаю сбоев, когда открывается диалоговое окно и происходит вращение. Состояние SupportFragmentManager хорошее и правильное в OnCreate. Временное исправление — заблокировать ориентацию экрана. Я запираю его на портрет, пока не разберусь с проблемой.




Ответы (1)


В ходе дальнейшего расследования я обнаружил, что зарегистрировался на событие в OnCreate и не смог отменить регистрацию, когда действие было уничтожено. Следовательно, обработчик событий по-прежнему будет отправлять сообщения старой активности, которая была уничтожена. Добавление этого в OnDestroy разрешило это исключение. Я тестировал это на Android 5.

person KevinSP    schedule 12.07.2015