栈操作时遇到一个问题
1 getFragmentManager().beginTransaction()
2 .replace(R.id.fl_container,bFragment)
3 .addToBackStack(null).commitNowAllowingStateLoss();
抛出异常:
1 java.lang.IllegalStateException: This transaction is already being added to the back stack
2 at androidx.fragment.app.BackStackRecord.disallowAddToBackStack(BackStackRecord.java:561)
3 at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:653)
4 at com.example.fragmentdemo.AFragment$1.onClick(AFragment.java:65)
-
看异常:已经被加入栈
那就去掉 .addToBackStack(null) 这句话,能正常显示fragment。但是还有一个就是按返回 或者别的操作要把上一个fragment从 BackStack 中拿出来 。而从fragment的回退栈中取东西 需要用:supportFragmentManager.popBackStackImmediate();
使用该方法却不能回退
-
分析:
回退栈中是否有这个fragment:supportFragmentManager.getBackStackEntryCount()
这个方法可以查看fragment回退栈的个数结果显示为0,并没有入栈
-
解决方案:
1 getFragmentManager().beginTransaction() 2 .replace(R.id.fl_container,bFragment) 3 .addToBackStack(null).commit();
这样就没有问题并且能够退回
-
思考: 为什么commitNowAllowingStateLoss()这个方法不能入栈
1 首先fragment事物的提交方式有四种: 2 3 /** 4 * 摘出其中的关键点 5 * it will be scheduled as work on the main thread 6 * to be done the next time that thread is ready. 7 * 不会立即执行 而是通过调度器有序的在主线程被执行 8 * 显然是可以被加入back stack 9 **/ 10 public abstract int commit(); 11 12 /** 13 * 该方法是 commit的加强版 支持在activity非活跃状态下提交事物 14 **/ 15 public abstract int commitAllowingStateLoss(); 16 17 /** 18 * Transactions committed in this way may not be added to the 19 * FragmentManager's back stack 20 * 了解到 这个方法 提交的fragment是不会被添加到 FragmentManager's back stack 21 **/ 22 public abstract void commitNow(); 23 24 /** 25 * 1类似commitNow();类似到什么程度呢?就是不会把fragment 加入fragment back stack栈。 看来是个加强版 26 * 2 the commit can be lost if the activity needs to later be restored from its state, 27 * 这个方法可以 在activity状态改变之后使用在activity非active状态的情况下是可以提交 并不会报错的 28 * 了解到 这个方法 提交的fragment是不会被添加到 FragmentManager's back stack 29 **/ 30 public abstract void commitNowAllowingStateLoss();
-
切入点:进入commitNowAllowingStateLoss这个方法看看怎么写的,我们看注释只能知其表,想知其理就需要看
FragmentTransaction
的实现类BackStackRecord
1 @Override 2 public int commit() { 3 return commitInternal(false); 4 } 5 6 @Override 7 public int commitAllowingStateLoss() { 8 return commitInternal(true); 9 } 10 11 @Override 12 public void commitNow() { 13 disallowAddToBackStack(); 14 mManager.execSingleAction(this, false); 15 } 16 17 @Override 18 public void commitNowAllowingStateLoss() { 19 disallowAddToBackStack(); 20 mManager.execSingleAction(this, true); 21 }
-
可以看出:是否加入BackStack取决于
disallowAddToBackStack()
方法1 @Override 2 public FragmentTransaction disallowAddToBackStack() { 3 if (mAddToBackStack) { 4 throw new IllegalStateException( 5 "This transaction is already being added to the back stack"); 6 } 7 mAllowAddToBackStack = false; 8 return this; 9 }
-
我的异常也是爆了这里有错误:disallowAddToBackStack(BackStackRecord.java:600)和切入点吻合