Android — невозможно уничтожить действие после завершения, вызванное IllegalStateException: невозможно выполнить это действие после onSaveInstanceState

У меня есть активность в моем приложении с 3 фрагментами. Когда кнопка нажимается на первом, в Activity вызывается метод, который выполняет какие-то не относящиеся к делу действия, а затем вызывает finish().

Это запускает onPause() для фрагмента, который выполняет более ненужные действия, а затем вызывает super.onPause().

Затем приложение загружает старую активность, в которой оно появилось (логически следуя стеку представлений), и внезапно аварийно завершает работу со следующим исключением, когда onDestroyView() вызывается во фрагменте:

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to destroy activity {be.niteowl.niteowl.debug/be.niteowl.niteowl.views.activities.VenueActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:2793)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:2811)
at android.app.ActivityThread.access$2100(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:972)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3835)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
at be.niteowl.niteowl.views.activities.TrackFragment.onDestroyView(TrackFragment.java:161)
at android.support.v4.app.Fragment.performDestroyView(Fragment.java:1665)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:980)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
at android.support.v4.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:1898)
at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:324)
at com.actionbarsherlock.app.SherlockFragmentActivity.onDestroy(SherlockFragmentActivity.java:88)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:2780)
... 11 more

Ошибка возникает при попытке удалить MapFragment из основного фрагмента. Я знаю, что у вас не должно быть фрагментов внутри фрагментов, но код работал в прошлом, и в любом случае это невозможно обойти.

@Override
public void onDestroyView() {
    SupportMapFragment f = (SupportMapFragment) activity.getSupportFragmentManager().findFragmentById(R.id.fragment_map);
    if (f != null) {
        activity.getSupportFragmentManager().beginTransaction().remove(f).commit();
    }
    super.onDestroyView();
}

Я уже искал исправление здесь, на SO (в первую очередь получение исключения IllegalStateException: невозможно выполнить это действие после onSaveInstanceState), но ни одно из них не применимо к моей текущей проблеме.


person Vindicator    schedule 17.07.2013    source источник
comment
Вы действительно убедились, что он работает до сохраненного состояния экземпляра?   -  person Broak    schedule 17.07.2013


Ответы (4)


Поскольку ваша активность уничтожается, ваши фрагменты будут автоматически уничтожены. Следовательно, вам не нужно их удалять. Просто удалите свой метод onDestroyView().

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

Во-первых, фрагменты внутри фрагментов поддерживаются через резервную копию фрагментов пакета поддержки Android и встроенную реализацию фрагментов Android 4.2+.

Во-вторых, вы не делаете фрагменты внутри фрагментов, по крайней мере, не на основе кода, показанного здесь. По какой-то причине ваш TrackFragment управляет другим фрагментом верхнего уровня (вашим SupportMapFragment), а не делегирует эту работу активности.

person CommonsWare    schedule 17.07.2013
comment
Спасибо, это действительно было чем-то вроде исправления. Однако теперь у меня возникают проблемы при переходе на 3-ю вкладку, а затем при возврате: НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: main android.view.InflateException: строка двоичного XML-файла № 96: ошибка раздувания фрагмента класса в android.view.LayoutInflater.createViewFromTag(LayoutInflater. java:587) ... (слишком длинный для этого комментария) - person Vindicator; 17.07.2013
comment
@Vindicator: Возможно, откройте новый вопрос StackOverflow, где вы можете показать всю трассировку стека и соответствующий код XML и Java. - person CommonsWare; 17.07.2013
comment
@Vindicator, похоже, это решает проблему: stackoverflow.com/a/17422251/732489 - person Quentin; 17.07.2013

Следующий код работал для меня. Он помещается во фрагмент, вызывающий фрагмент карты

@Override
public void onDestroy() {

    SupportMapFragment f = (SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.mapView);
    if (f.isResumed()){ 
        getFragmentManager().beginTransaction().remove(f).commit();
    }

    super.onDestroy();
}
person lytridic    schedule 12.04.2014
comment
спасибо, чувак, сбой произошел, когда я пытался закрыть приложение, и твой код это исправил - person NDM - Mobile DEV; 23.04.2014
comment
У меня тоже работал f.isResumed(), я просто использовал f != null (что, я думаю, должно быть и в вашем коде), большое спасибо! - person Analizer; 06.07.2014
comment
наконец! сделал это и для меня! - person lisa; 12.08.2014

Фиксация транзакций в обратном вызове OnPostResume() устранила проблему для меня. Спасибо за сообщение в блоге http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

@Override
protected void onPostResume() {
    super.onPostResume();
    // Commit your transactions here.
}
person Varun Bhatia    schedule 20.08.2014

Поскольку ваша активность уничтожается, что приводит к уничтожению фрагментов, .commit() не может быть обработан.

Удалить getSupportFragmentManager().beginTransaction().remove().commit().

Попробуйте обработать в onBackPressed(), что я и сделал для своего приложения.

person ranjith Gampa    schedule 28.07.2016