在onSaveInstanceState显示后无法执行此操作

Ant*_*ony 5 android android-fragments android-dialogfragment onsaveinstancestate

我收到以下崩溃报告:

致命异常:java.lang.IllegalStateException:无法在android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager)的android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1832)的onSaveInstanceState之后执行此操作. java:1850)在android.support.v4.app.BackStackRecord.com发布内部(BackStackRecord.java:643)android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:603)android.support.v4.app .DialogFragment.show(DialogFragment.java:143)

以下代码导致崩溃,为了清楚起见,我删除了一些简单的设置代码.我已经阅读了这个错误,据我所知,.show()在用户交互中应该是安全的onClick().我唯一能想到的是,这query()需要花费很长时间才能完成用户的交换.这是对这个错误的合理解释吗?即使使用大型数据库,它也会立即在我的设备上运行.还有其他可能吗?谢谢!

    foldersButton.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            final List<String> paths = new ArrayList<>();

            try(Cursor c = getActivity().getContentResolver().query(Meta.CONTENT_URI,
                    new String[]{"DISTINCT " + Meta.PARENT}, null, null,
                    Meta.PARENT + " ASC"))
            {
                while (c != null && c.moveToNext())
                {
                    String path = c.getString(c.getColumnIndex(Meta.PARENT));

                    // We place the excluded folders at the end
                    if (!mExcludedFolders.contains(path))
                        paths.add(path);
                }
            }

            [setup...]

            int[] position = new int[2];
            foldersButton.getLocationOnScreen(position);
            FolderDialog dialog = FolderDialog.newInstance(
                    paths.toArray(new String[paths.size()]),
                    visible,
                    excluded,
                    position[0],
                    position[1]);
            dialog.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.FolderDialog);

            [setup...]

            dialog.show(getFragmentManager(), TAG);
        }
    });
Run Code Online (Sandbox Code Playgroud)

Dib*_*nia 6

如果您的此代码在某个活动中,请将调用包装为show:

if(!isDestroyed() && !isFinishing())

如果此代码在片段内,请将调用包装为show:

if (isResumed() && !isRemoving())

这或多或少会解决在不一致的UI状态下登陆的问题


Nay*_*ava 0

您可以显示一个进度对话框,直到查询执行为止,让用户在屏幕上等待,同时通知他正在处理某些内容。

或者,如果您不想在这种情况下通知用户有关处理的信息,请检查活动是否仍在前台,然后才显示对话框。

您可以使用一个布尔变量isInForeground并分别在onResume和中设置/重置它onPause

 @Override
    protected void onPause() {
        super.onPause();
       isInForeground=false;
    }

    @Override
    protected void onResume() {
        super.onResume();
       isInForeground=true;
    }
Run Code Online (Sandbox Code Playgroud)

然后换行对话框在 if 条件下显示逻辑

if(isInForeground){
  dialog.show(getFragmentManager(), TAG);
}
Run Code Online (Sandbox Code Playgroud)