无法在onSaveInstanceState之后执行此操作 - DialogFragment

4

我已经重写了onSavedInstanceState并移除了super,我没有进行任何事务,更不用说在易变函数或异步函数中进行事务。

我正在调用它在一个自定义回调'onUserExistsListener'中。

        @Override
        public Boolean userExists(Boolean exists) {
            if (exists) {


            }
            else
            {
             AlertDialogFragment Frag = AlertDialogFragment.newInstance(0, null);
             Frag.show(getSupportFragmentManager(), "warndialog");
            }
   };

在其他的SO问题中尝试了所有建议,但仍然没有找到解决方案?有人能帮忙吗?

代码:

AlertDialogFragment Frag = AlertDialogFragment.newInstance(0, null);
 Frag.show(getSupportFragmentManager(), "warndialog");

流程:

OnCreate:(LoadNames函数)

LoadNames回调 -> 显示对话框。

接下来:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        add_name_to_db();
    }

功能:

public void add_name_to_db() {
        Details.checkNameExists(user_txt.getText().toString());
        Details.setOnUserExistsListener(new onUserExistsListener() {

            @Override
            public Boolean userExists(Boolean exists) {

                if (exists) 
                    {

                    } else {

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                AlertDialogFragment Frag = AlertDialogFragment.newInstance(0, null);
                                Frag.show(getSupportFragmentManager(), "warndialog");

                            }

                        });

                    }
                } else {
                    Toast.makeText(getApplicationContext(), "This is not a valid KIK username",
                            Toast.LENGTH_SHORT).show();
                }

                return exists;
            }

        });

    }

你能否再明确一下你的问题? - Eric Woodruff
您没有调用super.onCreate()吗?您必须这样做。 - MikeHelland
@rubenlop88 代码已添加!它一定与回调有关,但我就是想不出为什么。 - Broak
你的日志中是否出现了堆栈跟踪,程序是否崩溃?如果是,请修改你的问题... :) - t0mm13b
java.lang.IllegalStateException: 在 onSaveInstanceState 后无法执行 'Frag.show' 操作。 - Broak
显示剩余7条评论
3个回答

6
通过调用 Frag.show(getSupportFragmentManager(), "warndialog");实际上你正在执行一个Fragment事务(参见show())。
如果活动的 onSaveInstanceState() 方法已被调用,当你尝试显示对话框时将会抛出 IllegalStateException 异常。你需要改变代码确保在活动状态已经被恢复后(即在 onPostResume() 中)显示对话框片段。详见这篇博客文章获得更多信息。
你也可以提交事务并允许状态丢失,请参阅 commitAllowingStateLoss()

1
遗憾的是,提交允许状态丢失会导致以下错误:java.lang.IllegalStateException: Activity has been destroyed。 - Broak
1
如果活动已被销毁,则无法将片段附加到其中。要么更改为常规对话框,要么确保在活动处于活动状态且活动状态已恢复时进行提交。 - Luis
我已经制作了一个替代DialogFragment的解决方案,可以避免这个异常:https://github.com/AndroidDeveloperLB/DialogShard - android developer

0

编辑:在onCreate()中需要调用super.onCreate(SavedInstanceState)。如果没有调用,它就无法正常工作。


onSaveInstanceState() 方法在 Activity 即将结束时发生。在此期间停止并显示 UI 已经太晚了。

你希望这段代码什么时候运行?也许是当按下返回按钮时?

将你的代码放在 onBackPressed() 中。

Android:使用 Toast 正确使用 onBackPressed() 的方法

编辑 如果你想让代码在 Activity 开始时运行,正如你在另一个评论中提到的那样。不要使用 onSaveInstanceState()。 将你的代码放在 onCreate() 或 onResume() 中。


我根本没有使用保存的实例状态,我试图在普通函数中显示对话框,当活动远未进入暂停或保存实例的点时。 - Broak
在onCreate()中需要调用super.onCreate(SavedInstanceState),否则它将无法正常工作。 - MikeHelland
我已经在做那个了。如果我有什么地方让你感到困惑,对不起。现在我会再看一遍,看看能否以新的思路为它带来一些启示。 - Broak

-1
根据您的回调函数的工作方式,您可能需要在UI线程上运行这些代码行,如下所示:
runOnUiThread(new Runnable() {
    public void run() {
        AlertDialogFragment Frag = AlertDialogFragment.newInstance(0, null);
        Frag.show(getSupportFragmentManager(), "warndialog");

    }

});

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