Android之Fragment栈操作 commit()问题分析

栈操作时遇到一个问题

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();
     
  1. 切入点:进入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     }

     

  2. 可以看出:是否加入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     }
  3.  我的异常也是爆了这里有错误:disallowAddToBackStack(BackStackRecord.java:600)和切入点吻合

posted @ 2019-11-05 09:59  似鱼  阅读(1513)  评论(0编辑  收藏  举报