Vindicator Vindicator - 4 months ago 176
Android Question

Android - Unable to destroy activity after finish, caused by IllegalStateException: Can not perform this action after onSaveInstanceState

I have an activity in my app with 3 fragments. When a button is pushed on the first one, a method is called in the Activity that does some irrelevant stuff and then calls

finish()
.

This triggers
onPause()
on the fragment, which does more irrelevant stuff and then calls
super.onPause()
.

The app then loads the old Activity it came on (logically following the view stack), and suddenly crashes with the following exception when
onDestroyView()
is called on the Fragment:

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


The error appears to happen when trying to remove a
MapFragment
from the main Fragment. I know that you're not supposed to have fragments within fragments, but the code worked in the past and there's no way around it anyway.

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


I looked around for a fix here on SO already (most notably getting exception "IllegalStateException: Can not perform this action after onSaveInstanceState"), but none of them were applicable to my current problem.

Answer

Since your activity is being destroyed, your fragments will automatically be destroyed. Hence, there is no need for you to remove them. Simply delete your onDestroyView() method.

I know that you're not supposed to have fragments within fragments, but the code worked in the past and there's no way around it anyway.

First, fragments within fragments are supported via the Android Support package's backport of fragments and the native Android 4.2+ implementation of fragments.

Second, you are not doing fragments within fragments, at least not based on the code shown here. For some reason, your TrackFragment is managing another top-level fragment (your SupportMapFragment), rather than delegating that work to the activity.