5

我收到以下崩溃报告:

致命异常:java.lang.IllegalStateException:在 android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1832) 在 android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager. java:1850) 在 android.support.v4.app.BackStackRecord.commitInternal(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);
        }
    });
4

4 回答 4

6

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

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

如果此代码在片段中,则将调用包装为show

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

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

于 2017-02-04T11:45:54.347 回答
0

我越看它就越困扰我,我在 UI 代码中有一个查询。这可能是我测试这个概念的初始代码,当它起作用时我不小心离开了它。

有一个LoaderManager应用程序使用了错误的查询,但我使用现有的onLoadFinished来触发异步查询,该查询将在对 db 进行任何更改时更新路径结构。现在,当用户单击对话框时,就可以开始了。

由于我无法重现该错误,因此需要一周左右的时间才能对此做出判断,但无论哪种方式,先前的代码都是草率的。

于 2017-02-04T12:25:36.923 回答
0

您的活动似乎已暂停/您的应用不在前台。您可以在添加片段之前做一件事检查您的活动是否没有被破坏/完成并且您的应用程序是否处于前台(它没有最小化)

if(!isDestroyed()&&!isFinishing()&&isAppInForground(this)){
//add your fragment
}

编写代码来检查你的应用是否在前台

 /**
         *
         * @param context
         * @return boolean
         * tells whether user is currently viewing app or not if not return false otherwise true
         */
        public static boolean isAppInForground(Context context){
            boolean isInForeground = false;
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

                List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
                for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
                    if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                        for (String activeProcess : processInfo.pkgList) {
                            if (activeProcess.equals(context.getPackageName())) {
                                isInForeground = true;
                            }
                        }
                    }
                }

            return isInForeground;
        }
于 2017-06-19T09:00:02.193 回答
0

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

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

您可以使用一个布尔变量并分别isInForeground设置/重置它。onResumeonPause

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

    @Override
    protected void onResume() {
        super.onResume();
       isInForeground=true;
    }

然后在 if 条件中包装对话框显示逻辑

if(isInForeground){
  dialog.show(getFragmentManager(), TAG);
}
于 2017-02-04T11:25:23.380 回答