方向改变,FragmentTransaction,Activity已被破坏,WeakReference

时间:2013-03-22 17:43:01

标签: android android-fragments android-viewpager android-orientation

好的。我的第一个问题。我已经找到了一些解决方案,但老实说,并没有真正得到后台发生的事情。所以也许有人可以稍微清理一下这些东西。经过几天的调试后,我很高兴它的工作原理......希望我没有犯下一些严重的错误。我们来看看吧。

我有一些主要活动。只是一个FragmentActivity扩展JFeinstein’s SlidingFragmentActivity。此外,我决定采用片段方式,将任何内容(list-fragment,art​​icle-fragment,...)作为片段放入容器(滑动菜单的右侧);我的主要容器。到目前为止,非常好。

一个重要的片段是我的文章片段。一个ViewPager(带有FragmentStatePagerAdapter) - 包含一些带有文本和可能是另一个列表片段的页面。到目前为止仍然没有问题,直到我决定旋转设备。更准确地说,只要我不决定更新我的文章片段,旋转设备就会起作用。

我理解(纠正我,如果我错了)Android在旋转设备时自己处理片段状态。在我想重新加载/更新其内容之前,似乎一切都很好。

好的,让我们深入研究一下。 在第一次开始时,我得到了一些空的主容器。然后我第一次加载我的文章片段。只需获取SupportFragmentAdapter,创建我的ArticleFragment并用新创建的片段替换主容器 - 标记。没有火箭科学 - 只是一个简单的交易:

ViewPagerFragment pagerFragment = (ViewPagerFragment) 
    getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT_ARTICLE);

if(pagerFragment != null){
    if(pagerFragment.isResumed()){
        pagerFragment.triggerReload();
    }
} else {
    pagerFragment = new ViewPagerFragment();
    FragmentTransaction t = getSupportFragmentManager().beginTransaction();
    t.replace(R.id.id_main_root_frame, pagerFragment, TAG_FRAGMENT_ARTICLE);
    t.commitAllowingStateLoss();
}

为了避免每次重新加载内容时都创建一个片段,我试图在事务之前获取片段,如果找到并恢复,则触发对现有片段的重新加载。

现在我在这种状态下旋转设备。为了避免弄乱片段状态,我在片段内部保留了onSaveInstanceState()。所以我猜这个片段只是被破坏并重新创建。到目前为止,一切仍然有效。但我认为这部分有一个黑盒子。

之后 - 正常启动,创建片段并放入主容器,旋转设备 - 我触发一些更新。但是不是通过标签找到旧的(重新创建的)片段,而是找到了未发现的内容并创建并插入了新的片段。至少试图插入,因为这是我得到以下异常的地方:

java.lang.IllegalStateException: Activity has been destroyed

确切地说,当使用commitAllowingStateLoss()完成事务时,我得到上述异常。当我只提交()事务时,我得到以下异常:

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

这就是出现错误的地方。经过多年的调试和搜索后,我在this question/answer上找到了一些提示,以便在MainActivity的WeakReference上获取SupportFragmentManager。我该怎么说呢。自从我实现了它,它的工作原理。我不得不改变我的更新过程,但它确实有效。但是留下一些问题......

这种行为似乎很相似。第一次创作完美无缺。重新加载 - 标签找到片段。轮换后,文章仍然显示。当我重新加载具有该状态的片段时,它不会被标记找到,因此创建了一个新的,但commit() - 请求不会抛出异常。在调试器内部查看显示WeakReference是一些其他实例(其他id),而不是一个(this)所有这些都发生在那里。那就是我丢失情节的地方。 ..

如果你们中的一些人能给我一些提示,那就太好了! 提前谢谢!

1 个答案:

答案 0 :(得分:0)

试试这个:

commitAllowingStateLoss(); instead commit();