25.1.0和25.1.1版本中,片段回退堆栈行为出现问题

3
自从支持版本25.1.0和最新的25.1.1以来,我在替换/添加片段时遇到了奇怪的行为。有人报告了25.1.0的问题 Android - fragmentTransaction.replace()在support library 25.1.0上无法工作 但现在在25.1.1中我也遇到了类似的问题。为了重现这种行为,我创建了一个示例应用程序,您可以在https://github.com/holoduke/fragmenttest找到它。
基本上,这是一个带有片段容器的Activity。有几个可用的片段,通过按按钮动态地替换彼此。我们从MainActivity本身添加FragmentA。
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();

    Fragment f = new FragmentA();
    fm.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    f.setRetainInstance(false);
    ft.replace(R.id.fragmenttarget, f);
    ft.addToBackStack(null);
    ft.commit();

一切都很好,25.0.1、25.1.0和25.1.1都可以正常工作。

现在,在fragmentA中有3个按钮,它们将用fragmentA、fragmentB或fragmentC替换当前的fragment。

添加fragment B和C的代码与fragment A几乎相同,除了我们没有定义:

fm.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

当添加片段B或C时,将执行以下代码:
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();

    Fragment f = new FragmentB();
    f.setRetainInstance(false);
    ft.replace(R.id.fragmenttarget, f);
    ft.addToBackStack(null);
    ft.commit();

在版本25.0.1、25.1.0和25.1.1中,添加FragmentB和C多次后,fm.getBackStackEntryCount()会增加。

现在来看一下奇怪的部分。我们想使用popStackImmediate方法添加FragmentA(以清除历史记录)。这时候所有3个支持版本的行为都变得疯狂了。

假设您在所有3个版本中执行以下操作:

  1. 启动应用程序
  2. 替换为FragmentB
  3. 替换为FragmentC
  4. 替换为FragmentB
  5. 替换为FragmentC
  6. 替换为FragmentA

在25.0.1版本中,一切正常。回退栈被清除,在FragmentA中调用onCreateView和ActivityCreated方法。

在25.1.0版本中,替换为FragmentA后,onCreateView和ActivityCreated方法被调用了两次。不好。

在25.1.1版本中,更糟糕的是,在替换为FragmentA之后,回退栈中的所有视图都会调用onCreateView和ActivityCreated方法。现在很有趣,对吧 :)

只需尝试我的示例应用程序并查看logcat。更改app.gradle文件中的支持版本以查看差异。

希望有人能够认出这个问题,以便我们可以找到克服或解决此问题的方法。


您是否正在从Fragment本身替换Fragment?如果是,使用getChildFragmentManager() - 只需要澄清一下。 - Mark
请勿将翻译内容替换到MainActivity中。请参阅https://github.com/holoduke/fragmenttest/blob/master/app/src/main/java/com/test/fragment/gillis/testfragment/MainActivity.java。 - Gillis Haasnoot
1
我确认在25.1.1版本中,当弹出到堆栈中更深的片段时,所有中间的片段都会调用它们的onCreateView方法。这破坏了我的应用程序,在更新到25.1.1之前一直运行良好。降级到25.1.0解决了我的问题。然而,我的替代方案是A->B->C->D,与你的示例不同,所以我可能没有遇到你在25.1.0中提到的问题。 - Murat Ögat
1个回答

4

我曾经也遇到过相同的问题,并通过比较25.0.1 -> 25.1.1版本中的FragmentManager.class找到了解决方案。尝试使用FragmentTransaction的setAllowOptimization方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接