Java popBackStack()和replace()操作有何不同?
在管理片段时,我在应用程序中遇到了一些奇怪的行为,我想知道这样做是否有助于解释为什么会发生这种情况 我有两个片段,我们将它们称为片段A和片段B。我的应用程序的一般流程是,当用户以某种方式与片段A交互时,片段B通过调用Java popBackStack()和replace()操作有何不同?,java,android,android-fragments,Java,Android,Android Fragments,在管理片段时,我在应用程序中遇到了一些奇怪的行为,我想知道这样做是否有助于解释为什么会发生这种情况 我有两个片段,我们将它们称为片段A和片段B。我的应用程序的一般流程是,当用户以某种方式与片段A交互时,片段B通过调用fragmentTransaction.replace()(在所有情况下都会发生这种情况)来显示。当我显示片段B时,我将片段A添加到后堆栈中;然后,当用户按下片段B上的后退按钮时,片段A通过从后堆栈弹出再次显示 这很好,但是今天我发现片段B中有一个流,它调用fragmentTrans
fragmentTransaction.replace()
(在所有情况下都会发生这种情况)来显示。当我显示片段B时,我将片段A添加到后堆栈中;然后,当用户按下片段B上的后退按钮时,片段A通过从后堆栈弹出再次显示
这很好,但是今天我发现片段B中有一个流,它调用fragmentTransaction.replace()
,将片段B替换为当前位于后堆栈上的片段a的相同实例
这本身并没有什么问题,但是当我从片段A返回到片段B时,会出现奇怪的行为。如果我调用fragmentTransaction.replace()
,则不会调用片段B的onCreate()
方法
但是,如果我从后堆栈中弹出片段A,然后将其替换为片段B,则会触发片段B的onCreate()
方法。为什么会这样
请注意,片段A和片段B的所有实例都是在其主机活动启动时创建的
编辑以澄清。第二次调用
onCreate()
的情况如下:附加片段a=>替换为片段B,将片段a添加到后堆栈=>使用popBackStack()弹出片段a
=>再次用片段B替换片段A。这可能是因为片段管理器重用片段实例,而不是重新创建它。如果显示片段时需要执行片段B中的代码onCreate()
,则使用另一种方法移动代码,如onResume()
replace()
执行两项操作:
created
状态,其视图被销毁
现在popBackStack()
将撤消您添加到BackStack中的上一个事务
在这种情况下,这将是两个步骤:
onCreate()
调用,因为FragmentB仍然处于created
状态。问题第二部分的答案要长一点
首先,重要的是要理解,实际上并不是将片段
添加到Backstack,而是添加片段事务
。因此,当您认为“替换为片段B,将片段A添加到后堆栈”时,实际上是将整个操作添加到backbackback,即用B替换A。此替换包括两个操作-删除A和添加B
然后,下一步是弹出包含此替换的事务。所以你不是在弹出片段A,你是在反转“移除A,添加B”,反转的是“移除B,添加A”
最后一步应该更清楚——FragmentManager不知道B,所以当您在最后一步用B替换A来添加B时,B需要经历它的早期生命周期方法--onAttach()
和onCreate()
下面的代码说明了正在发生的事情
FragmentManager fm=getFragmentManager();
FragmentA FragmentA=新的FragmentA();
FragmentB FragmentB=新的FragmentB();
// 1. 展示
fm.beginTransaction()
.添加(碎片A,R.id.容器)
.commit();
// 2. 用B代替A
//FragmentManager保留对fragmentA的引用;
//它保持连接和创建;碎片B消失了
//通过生命周期方法onAttach()、onCreate()
//等等。
fm.beginTransaction()
.更换(碎片B,R.id.容器)
.addToBackstack(空)
.commit();
// 2'. replace()方法的替代方法
fm.beginTransaction()
.删除(碎片A)
.添加(碎片B,R.id.容器)
.addToBackstack(空)
.commit();
// 3. 反面(2);结果-A是可见的
//发生了什么:
//1)碎片B已从容器中移除,现在已分离;
//FragmentManager不再引用它
//2)碎片A实例放回容器中
//现在您的backbackback是空的,FragmentManager只知道
//断章取义
fm.popbackbackstack();
// 4. 秀B
//由于fragmentB被分离,它经历了早期的
//生命周期方法:onAttach()和onCreate()。
fm.beginTransaction()
.更换(碎片B,R.id.容器)
.addToBackstack(空)
.commit();
1。我编辑了我的问题,希望能进一步澄清。解决方案的奇怪之处在于,在这两种情况下,片段B似乎都进入分离状态,然后恢复<代码>popBackStack()必须执行不同的操作;我只是好奇那是什么。扩展我的答案,希望这能澄清问题。片段和它们的事务是一个非常复杂的主题。好吧,如果我手动用片段A替换片段B,那么另一个事务记录将添加到后堆栈中。这意味着FragmentManager仍然认为片段B处于分离状态。但是,当我弹出包含片段B的唯一事务时,FragmentManager认为不再附加该片段,因为没有包含它的事务。这是正确的理解吗?另外,感谢您提供的信息丰富的帮助。很高兴能提供帮助!我将试着一句一句地回答。(1) 我显示2'仅作为备选方案,带有eff