栈操作时遇到一个问题

 getFragmentManager().beginTransaction()
.replace(R.id.fl_container,bFragment)
.addToBackStack(null).commitNowAllowingStateLoss();

抛出异常:

 java.lang.IllegalStateException: This transaction is already being added to the back stack
at androidx.fragment.app.BackStackRecord.disallowAddToBackStack(BackStackRecord.java:561)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:653)
at com.example.fragmentdemo.AFragment$1.onClick(AFragment.java:65)
  • 看异常:已经被加入栈

    那就去掉 .addToBackStack(null) 这句话,能正常显示fragment。
    但是还有一个就是按返回 或者别的操作要把上一个fragment从 BackStack 中拿出来 。

    而从fragment的回退栈中取东西 需要用:supportFragmentManager.popBackStackImmediate();

    使用该方法却不能回退
  • 分析:

    回退栈中是否有这个fragment:supportFragmentManager.getBackStackEntryCount()这个方法可以查看fragment回退栈的个数
    结果显示为0,并没有入栈
  • 解决方案:

     getFragmentManager().beginTransaction()
    2 .replace(R.id.fl_container,bFragment)
    3 .addToBackStack(null).commit();

    这样就没有问题并且能够退回

  • 思考: 为什么commitNowAllowingStateLoss()这个方法不能入栈

     首先fragment事物的提交方式有四种:
    
     /**
    * 摘出其中的关键点
    * it will be scheduled as work on the main thread
    * to be done the next time that thread is ready.
    * 不会立即执行 而是通过调度器有序的在主线程被执行
    * 显然是可以被加入back stack
    **/
    public abstract int commit(); /**
    * 该方法是 commit的加强版 支持在activity非活跃状态下提交事物
    **/
    public abstract int commitAllowingStateLoss(); /**
    * Transactions committed in this way may not be added to the
    * FragmentManager's back stack
    * 了解到 这个方法 提交的fragment是不会被添加到 FragmentManager's back stack
    **/
    public abstract void commitNow(); /**
    * 1类似commitNow();类似到什么程度呢?就是不会把fragment 加入fragment back stack栈。 看来是个加强版
    * 2 the commit can be lost if the activity needs to later be restored from its state,
    * 这个方法可以 在activity状态改变之后使用在activity非active状态的情况下是可以提交 并不会报错的
    * 了解到 这个方法 提交的fragment是不会被添加到 FragmentManager's back stack
    **/
    public abstract void commitNowAllowingStateLoss();
     
  1. 切入点:进入commitNowAllowingStateLoss这个方法看看怎么写的,我们看注释只能知其表,想知其理就需要看FragmentTransaction的实现类BackStackRecord

      @Override
    public int commit() {
    return commitInternal(false);
    } @Override
    public int commitAllowingStateLoss() {
    return commitInternal(true);
    } @Override
    public void commitNow() {
    disallowAddToBackStack();
    mManager.execSingleAction(this, false);
    } @Override
    public void commitNowAllowingStateLoss() {
    disallowAddToBackStack();
    mManager.execSingleAction(this, true);
    }
  2. 可以看出:是否加入BackStack取决于disallowAddToBackStack()方法

      @Override
    public FragmentTransaction disallowAddToBackStack() {
    if (mAddToBackStack) {
    throw new IllegalStateException(
    "This transaction is already being added to the back stack");
    }
    mAllowAddToBackStack = false;
    return this;
    }
  3. 我的异常也是爆了这里有错误:disallowAddToBackStack(BackStackRecord.java:600)和切入点吻合

Android_Fragment栈操作 commit()问题分析的更多相关文章

  1. ElasticSearch Index操作源码分析

    ElasticSearch Index操作源码分析 本文记录ElasticSearch创建索引执行源码流程.从执行流程角度看一下创建索引会涉及到哪些服务(比如AllocationService.Mas ...

  2. 一文教你搞懂 Go 中栈操作

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/513 本文使用的go的源码15.7 知识点 LInux 进程在内存布 ...

  3. Python模拟入栈出栈操作

    目标: 1.编写菜单,提示用户操作选项(push,pop,view,quit) 2.规则:定义列表,先入栈,后出栈,后入栈,先出栈 1.模拟入栈.出栈操作 >>> list1 = [ ...

  4. 第一回写的用arraylist模拟栈操作

    package hashMap; import java.util.ArrayList; import d.Student; /** * 用ArrayList模拟栈操作 * @author zhuji ...

  5. c语言学习,模拟栈操作

    1.stack.c模拟栈操作函数的实现 #include<stdio.h> #include<stdlib.h> ; static char *stack;//数据栈 ;//栈 ...

  6. JavaScript中的栈及通过栈操作的实例

    <script> /*栈操作*/ function Stack() { this.dataStore = []; this.top = 0; this.push = push; this. ...

  7. php实现栈操作(不用push pop 库函数)

    直接上代码 <?php /*php不用库函数实现栈操作 * @author Geyaru 2019-04-20 */ class stack{ private $top = -1; //栈指针初 ...

  8. Lua和C++交互 学习记录之二:栈操作

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  9. 如何仅用递归函数和栈操作逆序一个栈——你要先用stack实现,再去改成递归——需要对递归理解很深刻才能写出来

    /** * 如何仅用递归函数和栈操作逆序一个栈 * 题目: * 一个栈依次压入1,2,3,4,5,那么从栈顶到栈底分别为5,4,3,2,1. * 将这个栈转置后,从栈顶到栈底为1,2,3,4,5,也就 ...

随机推荐

  1. 阿里云服务器CentOS6.9 tomcat配置域名访问

    之前一直是ip访问项目,今天申请到一个测试域名,想要用设置用域名访问项目. 1.进入阿里云服务器中,修改tomcat中server.xml文件 cd /usr/local/apache-tomcat/ ...

  2. jQuery常用方法(六)-jQuery 工具

    JQuery Utilities 方法说明 jQuery.browser .msie 表示ie jQuery.browser.version 读取用户浏览器的版本信息 jQuery.boxModel ...

  3. 体验Code::Blocks下的C++编程

    0.前言 在当前的行业发展和国际形势下,让更多的程序员思考跨平台编程问题.在众多的跨平台开发环境中,Code::Blocks具有独特的优势. 近二十年来,跨平台开发环境曾经如雨后春笋般产生,但是,由于 ...

  4. 夯实Java基础系列16:一文读懂Java IO流和常见面试题

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  5. 漫谈 GOF 设计模式在 Spring 框架中的实现

    原文地址:梁桂钊的博客 博客地址:http://blog.720ui.com 欢迎关注公众号:「服务端思维」.一群同频者,一起成长,一起精进,打破认知的局限性. 漫谈 GOF 设计模式在 Spring ...

  6. 为什么用Markdown,而不用Word?

    写博客.写文章比较多的人都知道 Markdown 是什么. Markdown 是一种轻量级标记语言,创始人为 John Gruber.它允许人们「使用易读易写的纯文本格式编写文档,然后转换成有效的 X ...

  7. 初探内核之《Linux内核设计与实现》笔记下

    定时器和时间管理 系统中有很多与时间相关的程序(比如定期执行的任务,某一时间执行的任务,推迟一段时间执行的任务),因此,时间的管理对于linux来说非常重要. 主要内容: 系统时间 定时器 定时器相关 ...

  8. 小白学 Python(1):开篇

    人生苦短,我用 Python 引言 大家好,可能大家都对我比较熟悉了,不熟悉请去面壁(现在熟悉一下也来得及)~ 简单做一个自我介绍,我是极客挖掘机的唯一作者,一位油腻的 Java 程序员[臭鸡蛋什么的 ...

  9. Creator3D 守护你的球球—UV动画与天空盒

    1 游戏预览 在线体验地址:http://example.creator-star.cn/follo-ball/ 2 场景物体 场景物体 新建场景后,引擎会为我们创建默认的摄像机和灯光,这个我们就不介 ...

  10. Kubernetes之Flannel介绍

    Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址. 在Kubernetes ...