android - getSupportFragmentManager() 导致 java.lang.IllegalStateException : Can not perform this action after onSaveInstanceState

标签 android android-asynctask android-fragmentactivity illegalstateexception android-support-library

我想弄清楚为什么:

getSupportFragmentManager().beginTransaction().commit();

失败,有

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

在一个非常基本的 FragmentActivity 类中。

这是我的用例(这将是一些伪代码而不是一个完整的例子,抱歉): 我有一个带有内部 AsyncTask 类的 FragmentActivity。大致是这样的:

public class HelloWorld extends FragmentActivity {
    showFragment(Fragment fragment, String name) {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer, fragment, name).commit();
    }

    private class SlowFragmentShow extends AsyncTask<Context, String, Void> {
        protected Void doInBackground(Context... contexts) {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                /* meh */
            }
        }

        protected void onPostExecute(Void nothing) {
            showFragment(new MyFragment(), "myFragment");
        }
    }
}

或者基本上,在启动应用程序 10 秒后,它会显示另一个 fragment 。听起来很简单,对吧?这似乎也很有效,直到我决定旋转手机。当我这样做时,应用程序会在调用“getSupportFragmentManager()...”并显示“无法执行此操作...”时崩溃。

最佳答案

经过多次调试,结果是当 SlowFragmentShow.onPostExecute() 被调用时,调用了 showFragment(),后者又调用了 getSupportFragmentManager( ),我收到了一个位于 IllegalState 中的 FragmentManager(因此可以说我得到的异常是正确的)。我仍然不确定为什么 getSupportFragmentManager() 会返回处于这种边缘状态的对象,但确实如此,我需要以某种方式访问​​“正确的”FragmentManager。 因此,切入正题,我将 FragmentManager 作为静态变量存储在我的 HelloWorld FragmentActivity 中,我在 HelloWorld.onStart() 时更新了它被称为:

public class HelloWorld extends FragmentActivity {
    private static FragmentManager fragmentManager;

    public void onStart() {
        fragmentManager = getSupportFragmentManager();
        /* more code here */
    }

    showFragment(Fragment fragment, String name) {
        fragmentManager.beginTransaction().replace(R.id.fragmentContainer, fragment, name).commit();
    }

    private class SlowFragmentShow extends AsyncTask<Context, String, Void> {
        protected Void doInBackground(Context... contexts) {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                /* meh */
            }
        }

        protected void onPostExecute(Void nothing) {
            showFragment(new MyFragment(), "myFragment");
        }
    }
}

好吧,这几乎解决了问题。现在我可以随心所欲地旋转手机,当 AsyncTask 完成时 fragment 仍会显示。

现在回想起来,确实有点“哦,当然!”,但 Android 背后的设计决策让人感觉相当“陌生”和不同寻常。我似乎以 try-catch(Exception) 结束了大约一半的代码,只是为了防止它因非 fatal error (例如未能更新文本字段)而崩溃,以及很多静态变量需要在 onStart() 上更新,因为这似乎是您引用 Android 对象而不让它们处于 IllegalState 中的唯一明智的方式。

关于android - getSupportFragmentManager() 导致 java.lang.IllegalStateException : Can not perform this action after onSaveInstanceState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17118383/

相关文章:

java - Android ViewPager 控件未出现在图形布局编辑器中

android - 设置 Sherlock ActionBar 的标题

java - AsyncTask onPostExecute 对话框不起作用

java - 使用AsyncTask在ListView中显示数据,但没有调用onPostExecute

java - 从 Android 应用程序传递值并显示在控制台上

java - 如何每次都从启动器图标启动MainActivity?

java - Android - 如何从 FragmentActivity 访问 fragment

android - 上传时未显示异步任务中的进度条

java - 从 GridView 中删除填充并使用整个 View 来放置项目

java - 在社交媒体上分享之前为照片添加水印