为什么我必须 "invalidate" 我的 window 才能避免碎片消失?

Why do I have to "invalidate" my window to avoid disappearing fragments?

我有一个功能齐全的应用程序,其中三个选项卡在三个片段之间切换。然后我对后端做了一些相当大的改变,但我认为没有什么会干扰 GUI。但它确实发生了——碎片现在往往会消失。

选项卡更改如下:

mActiveFragment = null;
switch (index) {
    case 0:
        mActiveFragment = new TabOneFragment();
        getSupportActionBar().setSubtitle("One");
        break;
    case 1:
        mActiveFragment = new TabTwoFragment();
        getSupportActionBar().setSubtitle("Two");
        break;
    case 2:
        mActiveFragment = new TabThreeFragment();
        getSupportActionBar().setSubtitle("Three");
        break;
}

getSupportFragmentManager().beginTransaction().replace(R.id.pnlTabContent, mActiveFragment).commit();

在我进行看似无关的更改之前,这工作得很好。现在,它工作了几次,然后片段容器保持为空,直到我关闭并重新打开 activity。

现在,我发现如果我在标签更改后添加此行,标签更改总是有效:

getWindow().addFlags(WindowManager.LayoutParams.LAYOUT_CHANGED);

或与此相关的任何其他标志。所以看来我现在需要刷新 window 以防止碎片消失。

关于为什么会发生这种情况有什么想法吗?我知道在没有看到我所做的更改的情况下很难调试,但由于它们非常大,并且分布在 20 多个不同的文件中,我认为共享它们没有任何意义。所以我正在寻找可能出错的一般想法。

嗯,当然,在处理这个问题五个小时后,我在此处发布问题后立即解决了它。

事实证明,我的其中一项更改是错误修复,用于修复在我的一个 ArrayAdapter 上调用 notifyDataSetChanged 时的 CalledFromWrongThreadException。由于此 class 无法访问任何 Activity,我在 UI 线程上使用了一个处理程序来 运行 它:

Handler mainHandler = new Handler(context.getMainLooper());
Runnable myRunnable = new Runnable() {
    @Override
    public void run() {
        adapter.notifyDataSetChanged();
    }
};
mainHandler.post(myRunnable);

出于某种原因,这对我的 activity 造成了影响。我不太了解处理程序,但我想我造成了某种不一致。我更改了代码,运行 它来自实际的 activity 的 运行OnUIThread(),现在一切都恢复正常了。