我收到了以下崩溃报告:
致命异常:java.lang.IllegalStateException:无法执行此操作 onSaveInstanceState之后的动作 在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);
}
});
答案 0 :(得分:6)
如果您的此代码在某个活动中,请使用以下内容将show
打包:
if(!isDestroyed() && !isFinishing())
如果此代码在片段内,请使用以下内容将调用包装到show
if (isResumed() && !isRemoving())
这或多或少会解决在不一致的UI状态下登陆的问题
答案 1 :(得分:0)
您可以显示进度对话框,直到查询执行,并让用户在屏幕上等待,同时通知他正在处理某些内容。
或者,如果您不想在这种情况下通知用户有关处理,请检查活动是否在前景中,然后显示对话框。
您可以使用一个布尔变量isInForeground
并分别在onResume
和onPause
中设置/重置它。
@Override
protected void onPause() {
super.onPause();
isInForeground=false;
}
@Override
protected void onResume() {
super.onResume();
isInForeground=true;
}
然后在if条件
中包装对话框显示逻辑if(isInForeground){
dialog.show(getFragmentManager(), TAG);
}
答案 2 :(得分:0)
我看的越多,我在UI代码中遇到查询就越困扰我。这可能是我测试这个概念的初始代码,当它工作时我不小心把它留下了。
使用错误查询的应用程序有LoaderManager
,但我使用现有的onLoadFinished
来触发异步查询,该查询将更新数据库的任何更改时的路径结构。现在当用户点击对话框时就可以了。
由于我无法重现错误,因此我可以在一周左右的时间内对此进行判决,但无论哪种方式,先前的代码都是草率的。
答案 3 :(得分:0)
您的活动似乎已暂停/您的应用不在foregraound中。在添加片段之前,您可以做一件事 检查您的活动是否未被销毁/完成,您的应用程序是否在前台(未最小化)
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;
}