关于FragmentTransaction的各种提交方法: commit(),commitAllowingStateLoss(),commitNow()commitNowAllowingStateLoss().
作者Bryan Herbst发了一个blog The many flavors of commit()讨论这几个方法的特点和用途.
下文是中文摘要.

FragmentTransaction的提交方法

support library的FragmentTransaction现在提供了四种不同的方法来commit一个transaction:
commit()
commitAllowingStateLoss()
commitNow()
commitNowAllowingStateLoss()

这篇文章分析了这四个方法的不同.

commit() vs commitAllowingStateLoss()

commit()提交有时候会遇到IllegalStateException, 说你在onSaveInstanceState()之后提交, 这里有另一个文章很好地分析了这个问题:Fragment Transactions & Activity State Loss
commit()commitAllowingStateLoss()在实现上唯一的不同就是当你调用commit()的时候, FragmentManger会检查是否已经存储了它自己的状态, 如果已经存了, 就抛出IllegalStateException.
那么如果你调用的是commitAllowingStateLoss(), 并且是在onSaveInstanceState()之后, 你可能会丢失掉什么状态呢?
答案是你可能会丢掉FragmentManager的状态, 即save之后任何被添加或被移除的Fragments.
举例说明:
1.在Activity里显示一个FragmentA;
2.然后Activity被后台, onStop()onSaveInstanceState()被调用;
3.在某个事件触发下, 你用FragmentB replace FragmentA , 使用的是 commitAllowingStateLoss().
这时候, 用户再返回应用, 可能会有两种情况发生:
1.如果系统杀死了你的activity, 你的activity将会重建, 使用了上述步骤2保存的状态, 所以A会显示, B不会显示;
2.如果系统没有杀死你的activity, 它会被提到前台, FragmentB就会显示出来, 到下次Activity stop的时候, 这个包含了B的状态就会被存下来.
(上述测试可以利用开发者选项中的”Don’t Keep Activities”选项).
那么你要选择哪一种呢? 这就取决于你提交的是什么, 还有你是否能接受丢失.

commit(), commitNow() 和 executePendingTransactions()

使用commit()的时候, 一旦调用, 这个commit并不是立即执行的, 它会被发送到主线程的任务队列当中去, 当主线程准备好执行它的时候执行.
popBackStack()的工作也是这样, 发送到主线程任务队列中去. 也即说它们都是异步的.

但是有时候你希望你的操作是立即执行的, 之前的开发者会在commit()调用之后加上 executePendingTransactions()来保证立即执行, 即变异步为同步.
support library从v24.0.0开始提供了 commitNow()方法, 之前用executePendingTransactions()会将所有pending在队列中还有你新提交的transactions都执行了, 而commitNow()将只会执行你当前要提交的transaction. 所以commitNow()避免你会不小心执行了那些你可能并不想执行的transactions.

但是你不能对要加在back stack中的transaction使用commitNow(), 即addToBackStack()commitNow()不能同时使用.
为什么呢?
想想一下, 如果你有一个提交使用了commit(), 紧接着又有另一个提交使用了commitNow(), 两个都想加入back stack, 那back stack会变成什么样呢? 到底是哪个transaction在上, 哪个在下? 答案将是一种不确定的状态, 因为系统并没有提供任何保证来确保顺序, 所以系统决定干脆不支持这个操作.

前面提过popBackStack()是异步的, 所以它同样也有一个同步的兄弟popBackStackImmediate().

所以实际应用的时候怎么选择呢?

  1. 如果你需要同步的操作, 并且你不需要加到back stack里, 使用commitNow().
    support library在FragmentPagerAdapter里就使用了commitNow()来保证在更新结束的时候, 正确的页面被加上或移除.
  2. 如果你操作很多transactions, 并且不需要同步, 或者你需要把transactions加在back stack里, 那就使用commit().
  3. 如果你希望在某一个指定的点, 确保所有的transactions都被执行, 那么使用executePendingTransactions().

Reference

这是Android Weekly #220的一篇文章, 我在做这期笔记的时候觉得这个写得很好, 所以决定单独拿出来说一说. 这期整体的笔记稍后推出, 敬请期待哇.
原文The many flavors of commit()

commit(), commitNow()和commitAllowingStateLoss()相关推荐

  1. commitallowingstateloss 和commit的区别

    1.什么是FragmentTransaction? 使用Fragment时,可以通过用户交互来执行一些动作,比如增加.移除.替换等. 所有这些改变构成一个集合,这个集合被叫做一个transaction ...

  2. Android Weekly Notes Issue #220

    Android Weekly Issue #220 August 28th, 2016 Android Weekly Issue #220 ARTICLES & TUTORIALS Manag ...

  3. Android app包下fragment详细使用

    文章目录 前言 一.什么是Fragment? 二.Fragment与Activity的区别与优势 1.生命周期不同 2.Fragment的使用优势 三.Fragment的生命周期 四.Fragment ...

  4. Fragment详解

    一.Fragment简介    Fragment是Android3.0后引入的一个新的API,它出现的初衷是为了适应大屏幕的平板电脑, 当然现在它仍然是平板APP UI设计的宠儿,而且我们普通手机开发 ...

  5. 大话Fragment管理

    大话Fragment管理 上一个项目遇到了一个Activity 管理30个Fragment的情况,刚开始的时候真的管理的焦头烂额,但是后来不停的研究api文档,渐渐的明白了android的Fragme ...

  6. Fragment Transactions和Activity状态丢失

    本文由 伯乐在线 - 独孤昊天 翻译.未经许可,禁止转载! 英文出处:androiddesignpatterns.欢迎加入翻译组. 下面的堆栈跟踪和异常代码,自从Honeycomb的初始发行版本就一直 ...

  7. android add fragment,fragment中的add和replace方法的区别浅析

    使用 FragmentTransaction 的时候,它提供了这样两个方法,一个 add , 一个 replace ,对这两个方法的区别一直有点疑惑. 我觉得使用 add 的话,在按返回键应该是回退到 ...

  8. SVN用法大全,SVN除了update、commit还有什么

    svn除了大家都知道的update.commit以外还有什么常用功能呢? 点击TortoiseSVN后,出现了右图的列表,这其中有哪些是常用的功能呢?最近在家办公,有些东西要svn操作,就了解了下. ...

  9. 规范的 Commit Message

    在 Angular 规范中,Commit Message 包含三个部分,分别是 Header.Body 和 Footer,格式如下: <type>[optional scope]: < ...

最新文章

  1. 第六十一节,html超链接和路径
  2. Jquery中attr与prop的区别
  3. (转)K-近邻算法(KNN)
  4. Linux CentOS 5.5 服务器安装图文教程
  5. 使用Azure Serverless来开发Teams App
  6. 八皇后问题---回溯
  7. ubtunu打开firefox_如何在Firefox(在Lubuntu中)中打开“apt”链接?
  8. html新增伪类,css3新增伪类有哪些
  9. 【概念集锦】之 shim和polyfill
  10. Python基础学习:svn导出差异文件脚本
  11. table中加表单元素怎么验证_使用element-ui +Vue 解决 table 里包含表单验证的问题...
  12. 优秀案例UI素材模板|深层解析iPhone手机APP页面怎么设计?
  13. nginx实现 二级目录跳转 子目录跳转
  14. 【LeetCode-SQL】1336. 每次访问的交易次数
  15. HDU 5143 NPY and arithmetic progression(思维)
  16. c语言基本变量类型以及其对应的占位符
  17. 能够997,是你们这些人修来的福报(手动滑稽)
  18. 大学计算机专业哪个学校最好,计算机专业:最好的7所大学!也是全中国“最难考”的大学!...
  19. andriod手机信号显示G、E、H、T是什么意思?
  20. pmp考前冲刺 项目管理中的工具与技术

热门文章

  1. C++移动构造函数以及move语句简单介绍
  2. 常用PDF编辑工具 Adobe Acrobat、PDF-XChange Editor 、福昕PDF编辑器、PDFelement
  3. log4net进阶手札(四):保存自定义对象到oracle
  4. iOS开发 - OC - 苹果为大家提供的后台:CloudKit 的简单使用
  5. JetBrains在CLion的Linux和OS X版本中引入Swift支持
  6. 通向架构师的道路(第十四天)Axis2 Web Service安全之rampart
  7. 通过输入方式在Android上进行微博OAuth登录
  8. LeetCode 100. Same Tree
  9. 【To Debug】牛客网--华为机试在线训练3:明明的随机数
  10. 【重点】剑指offer——面试题27:二叉搜索树与双向链表