转自:

http://www.tuicool.com/articles/q6R7nii

最新版本(v24.0.0)的 Support v4 库中的 FragmentTransaction 添加了 commitNow() 和 commitNowAllowingStateLoss () 两个函数,这样 提交一个 Fragment 就有如下4个函数可以选择:

– commit()

– commitAllowingStateLoss()

– commitNow()

– commitNowAllowingStateLoss()

另外,在使用 Fragment 的过程中,可能您已经使用过了 executePendingTransactions() 这个函数了。

下面来深入分析下每个函数是干啥用的,你应该使用哪个函数。

commit() vs commitAllowingStateLoss()

大部分使用 Fragment 的开发者可能都遇到过如下的异常:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

Alex Lockwood 写过一篇文章来详细解释为何会出现该异常。但是开发者更多的是想知道他们的应用出现了该问题意味着什么?

commit() 和 commitAllowingStateLoss() 的实现几乎是一样的。唯一的区别就是在调用 commit() 的时候 FragmentManager 会检查是否已经保存了其状态,如果状态已经保存了,则就抛出 IllegalStateException 异常。

那么,在 onSaveInstanceState() 函数执行以后,您调用 commitAllowingStateLoss() 会丢失那些状态呢? 答案就是你可能丢失 FragmentManager 的状态,这里面包含在 onSaveInstanceState() 执行之后添加和删除的 Fragment。

例如:

1. 当前您的 Activity 在显示 FragmentA

2. 您的 Activity 被切换到后台了((onStop() 和 onSaveInstanceState() 函数被调用了)

3. 这个时候您的 Activity 的逻辑发生了一些变化,您使用 FragmentB 替换了 FragmentA 并调用了 commitAllowingStateLoss() 函数来提交这个变化。

这个时候,当用户再次切回您的 Activity 的时候可能出现如下两种状态:

  1. 如果系统内存不足并且杀死了您的应用,当用户重新打开您的 应用的时候,系统将会恢复您的应用到上面第二步的状态,而 FragmentB 是不会显示的。
  2. 如果系统没有杀死您的应用,用户则可以看到 FragmentB。当 Activity 再次回到后台的时候(onStop), FragmentB 的状态才会被保存起来。

Github 上有个示例项目 演示该情况。在运行该示例的时候,如果打开开发者选项中的 “Don’t Keep Activities” 设置,则可以用来显示第一种情况,FragmentB 的状态完全丢失了。 如果没有打开 “Don’t Keep Activities” 选项,则可以查看第二种情况。

这两个函数使用哪个取决于您提交的 Fragment 和 该 Fragment 状态是否重要,如果状态丢失了也没关系,则您可以使用 commitAllowingStateLoss() 函数。

commit(), commitNow(), 和 executePendingTransactions()

其他版本的 commit() 指定了提交发生的时机。 commit() 的文档有如下说明:

安排一个针对该事务的提交。提交并没有立刻发生,会安排到在主线程下次准备好的时候来执行。 (Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.)

上面文档说明的意思是,你可以同时执行多次提交,这些提交都没有立刻执行,知道下次主线程准备好了才一起执行这些提交的 Fragment。这些针对 Fragment 的提交操作包含 添加、删除、替换以及通过函数 popBackStack() 来返回前一个 Fragment。

有时候,您需要针对 Fragment 的操作立刻执行。之前都是通过在调用函数 commit() 后调用 executePendingTransactions() 来实现的。

在 24.0.0 版本的 Support 库中添加了 commitNow() 函数来更好的支持这种操作。commitNow() 只同步的执行当前的提交操作,而 executePendingTransactions() 则会执行所有等得执行的操作。 commitNow() 可以避免您执行之前提交的但是无需立刻执行的操作。

commitNow() 有个限制,无法把当前提交的 Fragment 添加到堆栈(back stack)中。假设有如下的情况:

通过 commit() 函数把 Fragment A 添加到堆栈中,然后立刻使用 commitNow() 把另外一个 Fragment B 添加到堆栈中,这样当前的堆栈应该是何种状态? 是 Fragment A 在前面还是 Fragment B 在前面呢?

popBackStack() 和 popBackStackImmediate() 与 commit() 和 commitNow() 的情况是一样的。

最后来总结下该如何选择这些函数:

  • 如果你需要同步提交 Fragment 并且无需添加到 堆栈 中,则使用 commitNow()。 Support 库中在 FragmentPagerAdapter 中使用这个函数,来确保更新 Adapter 的时候 正确的页面被添加和删除了。一般来说,只要不添加到堆栈中,都可以使用这个函数来提交。
  • 如果执行了多次提交,并且不需要是同步的,或者把每次提交都添加到 堆栈 中,那么就使用 commit()。
  • 如果 您需要把多次提交操作的同一个时间点一起执行,则使用 executePendingTransactions()

选择正确的 Fragment#commitXXX() 函数的更多相关文章

  1. [转]oracle设计数据库应选择正确的数据类型

    原文地址:http://blog.sina.com.cn/s/blog_5014663501007n40.html 在设计数据库的时候,选择正确的数据类型,往往可以避免很多的问题,正确理解数据库的类型 ...

  2. JavaScript是如何工作: 深入探索WebSocket和HTTP/2与SSE + 如何选择正确的路径!

    原文:<JavaScript是如何工作: 深入探索 websocket 和HTTP/2与SSE +如何选择正确的路径! 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 文章底部分 ...

  3. (转)C# 选择正确的集合

    原文: http://www.cnblogs.com/luminji/archive/2011/03/24/1993393.html 要选择正确的集合,我们首先要了解一些数据结构的知识.所谓数据结构, ...

  4. 改善C#程序的建议3:在C#中选择正确的集合进行编码

    要选择正确的集合,我们首先要了解一些数据结构的知识.所谓数据结构,就是相互之间存在一种或多种特定关系的数据元素的集合.结合下图,我们看一下对集合的分类. 集合分类 在上图中,可以看到,集合总体上分为线 ...

  5. 如何选择正确的DevOps工具

    坦白的讲:世界上没有哪种工具能够像DevOps这么神奇(或敏捷,或精益).DevOps在开发和运营团队之间建立了完美的合作与沟通,因此与其说这是一种神奇的工具,不如说是一种文化的转变. 然而,团队之间 ...

  6. WCF开发时如何选择正确的实例模式(InstanceMode)?

    WCF开发时如何选择正确的实例模式(InstanceMode)?   在使用WCF实例模型时,你是否思考过这几个的问题: ”WCF中的实例模式如何正确应用”? ”使用WCF中的实例模式有何原则可以遵循 ...

  7. [No000017A]改善C#程序的建议3:在C#中选择正确的集合进行编码

    要选择正确的集合,我们首先要了解一些数据结构的知识.所谓数据结构,就是相互之间存在一种或多种特定关系的数据元素的集合.结合下图,我们看一下对集合的分类. 集合分类 在上图中,可以看到,集合总体上分为线 ...

  8. (转)权威支持: 选择正确的 WebSphere 诊断工具

    权威支持: 选择正确的 WebSphere 诊断工具 原文:https://www.ibm.com/developerworks/cn/websphere/techjournal/0807_supau ...

  9. [转] 如何选择正确的Hadoop版本

    Gartner:如何选择正确的Hadoop版本 这份报告的全名是<How to Choose the Right Apache Hadoop Distribution>.主要介绍了企业如何 ...

随机推荐

  1. 线性分类 Linear Classification

    软分类:y 的取值只有正负两个离散值,例如 {0, 1} 硬分类:y 是正负两类区间中的连续值,例如 [0, 1] 一.感知机 主要思想:分错的样本数越少越好 用指示函数统计分错的样本数作为损失函数, ...

  2. Spring Boot Security Oauth2之客户端模式及密码模式实现

    Spring Boot Security Oauth2之客户端模式及密码模式实现 示例主要内容 1.多认证模式(密码模式.客户端模式) 2.token存到redis支持 3.资源保护 4.密码模式用户 ...

  3. websocket初体验(小程序)

    之前上个公司做过一个二维码付款功能,涉及到websocket功能,直接上代码 小程序onShow方法下加载: /** 页面的初始数据 **/ data: { code: "", o ...

  4. 记几个 DOM 操作技巧

    使用 attributes 属性遍历元素特性 // 迭代元素的每一个特性,将它们构造成 name = value 的字符串形式 function outputAttributes (element) ...

  5. ServerResponse(服务器统一响应数据格式)

    ServerResponse(服务器统一响应数据格式) 前言: 其实严格来说,ServerResponse应该归类到common包中.但是我实在太喜欢这玩意儿了.而且用得也非常频繁,所以忍不住推荐一下 ...

  6. 【redis】redis基础命令学习集合

    写在前面 Redis是一个高速的内存数据库,它的应用十分广泛,可以说是服务端必学必精的东西.然而,学以致用,无用则无为.学了的东西必须反复的去用,去实践,方能有真知.这篇文章记录了我在redis学习过 ...

  7. SpringBoot:Java High Level REST Client 搜索 API

    Springboot整合最新版elasticSearch参考之前的文章:SpingBoot:整合ElasticSearch 7.2.0 Search API SearchRequest用于与搜索文档, ...

  8. Windows上快捷登陆应用程序

    在Windows上有些程序双击后,还需要输入用户名密码等,填写很多信息后才开始使用. 有些程序本身实现了保存信息,或者可以自动登陆. 但也有些程序无信息保存和自动登陆功能,如果经常使用,每次都填写觉得 ...

  9. Codeforces 814D

    题意略. 思路: 由于不重合这个性质,我们可以将每一个堆叠的圆圈单独拿出来考虑,而不用去考虑其他并列在同一层的存在, 在贪心解法下,发现,被嵌套了偶数层的圆圈永远是要被减去的,而奇数层的圆圈是要加上的 ...

  10. [目录] ASP.Net Core 搭建微服务网站

    本项目采用ASP.Net Core微服务技术,搭建博客和Saas平台. 全文将围绕(1)设计模式  (2)敏捷开发 目的: 结构足够合理,代码足够优美,扩展性.可读性.易维护性做到最优. 以下目录仅为 ...