zoukankan      html  css  js  c++  java
  • 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)和切入点吻合

  • 相关阅读:
    将博客搬至CSDN
    IDEA安装对应版本的lombok才生效
    shift键复选dataGrid的记录时多余的文本总被选择了。
    git 导出新修改的文件
    svn老鸟转用git必须理解的概念
    java中Long类型和long类型的大小比较
    eclipse反编译插件jadClipse安装使用教程
    js闭包
    java泛型讲解
    常用加密解密算法【RSA、AES、DES、MD5】介绍和使用
  • 原文地址:https://www.cnblogs.com/jiani/p/11796662.html
Copyright © 2011-2022 走看看