首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在显示对话框时,我得到“Can not perform this action after onSaveInstanceState”

在显示对话框时,我得到“Can not perform this action after onSaveInstanceState”
EN

Stack Overflow用户
提问于 2013-03-31 19:57:30
回答 17查看 62.6K关注 0票数 132

一些用户报告说,如果他们使用通知栏中的快速操作,他们将被强制关闭。

我在通知中显示了一个快速操作,该操作调用

"TestDialog“

类。在TestDialog类中,按下"snooze“按钮后,我将显示SnoozeDialog。

代码语言:javascript
复制
private View.OnClickListener btnSnoozeOnClick() {
    return new View.OnClickListener() {

        public void onClick(View v) {
            showSnoozeDialog();
        }
    };
}

private void showSnoozeDialog() {
    FragmentManager fm = getSupportFragmentManager();
    SnoozeDialog snoozeDialog = new SnoozeDialog();
    snoozeDialog.show(fm, "snooze_dialog");
}

错误是

触发IllegarStateException的代码行是:

代码语言:javascript
复制
snoozeDialog.show(fm, "snooze_dialog");

类扩展"FragmentActivity“,"SnoozeDialog”类扩展"DialogFragment“。

下面是错误的完整堆栈跟踪:

代码语言:javascript
复制
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 android.support.v4.app.DialogFragment.show(DialogFragment.java:127)
at com.test.testing.TestDialog.f(TestDialog.java:538)
at com.test.testing.TestDialog.e(TestDialog.java:524)
at com.test.testing.TestDialog.d(TestDialog.java:519)
at com.test.testing.g.onClick(TestDialog.java:648)
at android.view.View.performClick(View.java:3620)
at android.view.View$PerformClick.run(View.java:14292)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4507)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)

我不能重现这个错误,但是我收到了很多错误报告。

有人能帮我吗?我该如何修复这个错误呢?

EN

回答 17

Stack Overflow用户

发布于 2016-02-16 19:22:00

这很常见

问题

..。我们通过重写show()和处理DialogFragment扩展类中的异常解决了这个问题

代码语言:javascript
复制
public class CustomDialogFragment extends DialogFragment {

    @Override
    public void show(FragmentManager manager, String tag) {
        try {
            FragmentTransaction ft = manager.beginTransaction();
            ft.add(this, tag);
            ft.commit();
        } catch (IllegalStateException e) {
            Log.d("ABSDIALOGFRAG", "Exception", e);
        }
    }
}

请注意,应用此方法不会更改DialogFragment.class的内部字段:

代码语言:javascript
复制
boolean mDismissed;
boolean mShownByMe;

在某些情况下,这可能会导致意想不到的结果。最好使用commitAllowingStateLoss()而不是commit()

票数 70
EN

Stack Overflow用户

发布于 2014-09-07 09:20:34

这意味着你

(

如果是DialogFragment)之后的片段

..。

Android会将你的片段状态保存在

..。所以,如果你

片段后

片段状态将丢失。

因此,如果Activity被终止并在稍后重新创建,片段将不会添加到activity中,这是糟糕的用户体验。这就是为什么Android不允许不惜一切代价进行状态丢失。

简单的解决方案是检查状态是否已经保存。

代码语言:javascript
复制
boolean mIsStateAlreadySaved = false;
boolean mPendingShowDialog = false;

@Override
public void onResumeFragments(){
    super.onResumeFragments();
    mIsStateAlreadySaved = false;
    if(mPendingShowDialog){
        mPendingShowDialog = false;
        showSnoozeDialog();
    }
}

@Override
public void onPause() {
    super.onPause();
    mIsStateAlreadySaved = true;
}

private void showSnoozeDialog() {
    if(mIsStateAlreadySaved){
        mPendingShowDialog = true;
    }else{
        FragmentManager fm = getSupportFragmentManager();
        SnoozeDialog snoozeDialog = new SnoozeDialog();
        snoozeDialog.show(fm, "snooze_dialog");
    }
}

注意: onResumeFragments()将在片段恢复时调用。

票数 29
EN

Stack Overflow用户

发布于 2016-10-21 02:25:31

代码语言:javascript
复制
private void showSnoozeDialog() {
    FragmentManager fm = getSupportFragmentManager();
    SnoozeDialog snoozeDialog = new SnoozeDialog();
    // snoozeDialog.show(fm, "snooze_dialog");
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.add(snoozeDialog, "snooze_dialog");
    ft.commitAllowingStateLoss();
}

参考:

链接

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15729138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档