Android - 无法在finish后销毁activity,由IllegalStateException引起: 在onSaveInstanceState之后不能执行此操作。

16

我的应用程序中有一个包含3个片段的活动。当在第一个片段上按下按钮时,Activity中将调用一个方法来执行一些无关紧要的操作,然后调用finish()

这将触发片段中的onPause()方法,该方法将执行更多无关紧要的操作,然后调用super.onPause()

随后,应用程序会加载之前经过的Activity(逻辑上遵循视图堆栈),但是当片段上调用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: Can not perform this action after onSaveInstanceState"),但它们都不适用于我当前的问题。


你确定在保存实例状态之前它已经运行了吗? - Broak
5个回答

20
以下代码适用于我。它位于调用地图片段的片段中。
@Override
public void onDestroy() {

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

    super.onDestroy();
}

谢谢,伙计。崩溃是在我试图关闭应用程序时发生的,你的代码修复了它。 - NDM
2
f.isResumed() 对我也有效,我只是在使用 f != null(我认为你的代码中也应该有),非常感谢! - Analizer
终于!对我也管用了! - lisa

8
由于您的活动被销毁,您的片段将自动被销毁。因此,您无需删除它们。只需删除您的onDestroyView()方法即可。

我知道你不应该在片段中嵌套片段,但是代码过去可以工作,而且无论如何都没有办法解决。

首先,通过Android支持包的片段后退和本机Android 4.2+实现的片段,支持片段中的片段。
其次,根据此处显示的代码,您并没有在片段中嵌套片段。由于某种原因,您的TrackFragment正在管理另一个顶级片段(即您的SupportMapFragment),而不是将该工作委托给活动。

谢谢,那确实算是个解决方法。然而,现在我遇到问题了,当我跳转到第三个标签页再返回时:FATAL EXCEPTION: main android.view.InflateException: Binary XML file line #96: Error inflating class fragment at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:587) ... (过长不在此列举) - Vindicator
@Vindicator:或许可以在 StackOverflow 上开一个新问题,展示完整的堆栈跟踪和相关的 XML 和 Java 代码。 - CommonsWare
@Vindicator 这似乎解决了问题:https://dev59.com/g-o6XIcBkEYKwwoYNBpn#17422251 - Quentin

0
我使用以下代码在活动中修复了它:
 @Override
    public void onDestroy() {
        try{
            super.onDestroy();
        }catch (NullPointerException e){

        }
    }

0

0

当您的活动被销毁时,会导致片段被销毁,因此无法处理.commit()。

请删除getSupportFragmentManager().beginTransaction().remove().commit()。

尝试在onBackPressed()中处理,这是我为我的应用程序所做的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接