【问题标题】:Fragment IllegalStateException - commit() causing state lossFragment IllegalStateException - commit() 导致状态丢失
【发布时间】:2018-11-09 21:26:57
【问题描述】:

我有一个显示 3 个选项卡的 FragmentStatePagerAdapter,其中第一个选项卡(片段)在其 onCreateView() 中提交了 FragmentTransaction。对于某些用户,我看到由 commit() 状态丢失引起的 IllegalStateException。

在阅读了一些堆栈溢出问答和 Alex Lockwood 在Fragment Transactions and Activity State Loss 上的博客文章后,我更好地了解了导致状态丢失的原因,我可以采取多种方法。

  1. 我可以将片段提交移至 onPostResume。
  2. 我可以将我的片段提交移动到 onCreate() - 可能是最安全的。

但是,onCreateView() 内部有很多逻辑,如果我采用上述方法,我可能会引入回归错误。我想知道,因为 onCreate() 最终会调用 onCreateView(),是否可以只检查 savedInstanceState 是否为空。这能解决问题吗?

这是我当前的代码:

@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
    FFragment frag = new FFragment();
    frag.setDateSelected(mDateSelected);
    getFragmentManager().beginTransaction()
            .add(R.id.container, frag, FRAG_TAG)
            .commit();
    ...
}

我想什么会修复状态损失:

@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
    if(savedInstanceState == null) {
        frag = new FFragment();
        frag.setDateSelected(mDateSelected);
        getFragmentManager().beginTransaction()
                .add(R.id.container, frag, FRAG_TAG)
                .commit();
    } else {
        frag = (FFragment) getSupportFragmentManager()
            .findFragmentByTag(FRAG_TAG);
    }
    ...
}

我为什么要问这个而不只是实现和测试它?我试图通过 ADB 和 DDMS 终止活动,但无法重现状态丢失 - 因此询问这种方法是否可行。或者,我是否必须做不可避免的事情并将提交移至 onCreate 或 onPostResume()?

还有其他方法可以测试触发状态丢失吗?

【问题讨论】:

  • 你听说过 FragmentStatePagerAdapter 吗?这可能会有所帮助
  • @Deepakkaku 对不起,我应该写的。我正在使用它,只是对问题进行了编辑。

标签: android android-fragments android-activity illegalstateexception


【解决方案1】:

你错了几件事

  1. 您在片段中使用 getFragmentManager() 和 getSupportFragmentManager(),在使用嵌套片段时应始终使用 getChildFragmentManager()

  2. Alex 谈到的 OnResumeFragments() 和 onCreate 是关于活动而不是片段,framgent 内部没有这样的方法

  3. 您提出的解决方案是完全不同的,它在从后台重新创建活动时使用

解决方案是将代码移动到片段的 onViewCreated() 方法并使用 childFragmentManager,我在片段中使用 viewpager,并在 onViewCreated() 中对其进行初始化,到目前为止还没有遇到任何此类问题

【讨论】:

  • 知道了,感谢您的第1点和第2点。但是对于第3点,如果活动在后台被系统杀死,当用户返回时不会重新创建它应用程序?因此,由于提交片段事务而造成状态丢失。
  • 当activity重新创建时,这个fragment会自动被附加,我们不需要再次添加它,因此我们检查了savedInstanceState,以确保我们只在第一个fragment时附加它创建而不是重新创建时
  • 当您尝试在活动完全创建之前提交任何片段事务时,即在调用活动的 onResumeFragments 之前,会出现此特定问题。
猜你喜欢
  • 2020-04-12
  • 1970-01-01
  • 2014-11-22
  • 2021-07-28
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-19
相关资源
最近更新 更多