FragmentTransaction&Activity的状态

LC滤波器设计实战:从理论计算到PCB布局的完整指南 滤波器是信号处理与电路设计中的基础组件,用于从复杂信号中提取特定频率分量或抑制干扰噪声。其核心原理基于电感(L)和电容(C)等无源元件的频率选择特性,通过特定的网络拓扑实现幅频与相频特性的塑造。在工程实践中,LC滤波器因其结构简单、可靠性高、成本可控,成为射频、模拟及电源电路中的关键技术手段。其设计价值在于将理论网络综合转化为可量产、高性能的硬件解决方案,广泛应用于通信系统、音频处理、电源净化和传感器信号调理等场景。本文聚焦于LC滤波器的工程设计全流程,深入剖析了巴特沃斯、切比雪夫等经典类型的选型权衡,并重 阅读详情
转自http://my.oschina.net/u/724985/blog/287468
个人翻译的国外大牛博客 原文链接

自从Android Honeycomb发布以来,下面的异常信息和trace已经在StackOverflow提出了很多了:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1341)
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1352)
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)

这篇博文会解释这个异常信息为什么会产生,什么时候会被抛出。并且通过提供几个建议确保你的App再也不会因此而挂掉。

为什么会产生这个异常

当Activity状态(state)已经被保存之后,而你又试图提交一个Fragment事务,系统就会抛出这个异常,直接导致的现象就是Activity的状态丢失了。在我们深入问题之前,让我们先看一下当onSaveInstanceState()被调用时系统做了什么。就像我以前博文Binders & Death Recipients里所说的,Android应用程序很难控制自己的命运。Android有能力在任何时候干掉进程去释放内存,并且后台活动可能毫无预兆地被干掉。为了确保用户有时的意外行为,系统框架通过在Actvitiy被干掉之前调用onSaveInstanceState()方法去保存Activity的状态。当保存的状态呗还原后,用户能够在切换前台和后台活动时感受到无缝切换,而不用考虑活动是否已经被系统干掉了。

当系统调用onSaveInstanceState()方法时,系统传递了一个Bundle对象好让Activity能够保存它的状态,之中Activity保存的状态包括对话框、Fragment和各种视图等。当这个方法返回后,系统会序列化Bundle对象通过Binder接口安全的存放在系统进程中。当系统决定重新创建这个Activity后,系统会发送同样的Bundle到这个应用,被用来还原Acitivity的老的状态。

那么为什么会抛出这个异常呢?这个问题的实质就是当Activity调用onSaveInstanceState()方法后,Bundle对象保存了这个Activity的“快照”。这就意味着当你在onSaveInstanceState()被调用之后调用的FragmentTransaction#commit(),因为Activity已经保存了当前的状态并且不会记录这个事务,这个事务的提交就不会被记住。从用户的角度来看,这个事务会被丢掉,导致UI的状态丢失。为了保证用户体验,Android不惜一切避免状态丢失,当它发生的时候,就直接爆出一个IllegalStateException异常。

什么时候会抛出这个异常

如果你以前遇见过这个异常,或许你已经注意到不同版本平台异常抛出的时间略有不同。例如,你可能发现老设备更少地抛出这个异常,或者你的应用更可能crash在使用support库而不是官方系统库。这就导致了很多人控诉support库有bug并且不可信。事实上,这些控诉都是不正确的。

这些不一致的现象的原因是因为Honeycomb版本对Activity的生命周期做了重大的修改。在Honeycomb之前,Activity在被暂停之前是不可被杀的,这意味着onSaveInstanceState()是在onPause()之前调用的。自从Honeycomb版本,Activity只能在停止以后是可被杀的,意味着onSaveInstanceState()会在onStop()之前调用,而不是在onPause()之前调用。总结如下:

 Honeycomb之前Homeycomb之后
Activity能在onPause()之前被干掉NONO
Activity能在onStop()之前被干掉YESNO
onSaveInstanceState(Bundle)通常在哪个方法之前调用?onPause()onStop()

因为Activity生命周期的改变,support库有时需要根据平台版本的不同而改变它的行为。例如,设备运行在Honeycomb或以上的系统,每次在onSaveInstanceState()后调用commit()方法,系统都会抛出异常去警告开发者发生了状态丢失。然而,每次都抛出一个异常是过于严格的在设备运行Honeycomb以前的系统,它们的onSaveInstanceState()在Activity生命周期中被更早的调并且更容易导致状态丢失。Android团队不得不做出了妥协:在了在老系统上拥有更好的交互操作,在onPause()和onStop()之间,老设备只能承受状态丢失。Support库在不同版本上不同的行为可总结为:

 Honeycomb之前Homeycomb之后
commit()在onPause()之前OKOK
commit()在onPause()和onStop()之间STATE_LOSSOK
commit()在onStop()之后EXCEPTIONEXCEPTION

如何避免这个异常?

一旦你理解了这个异常的实质情况,避免这个异常就变的非常简单了。如果你已经做到了这一步,希望你能理解Support是怎样工作的,并且为什么在应用中避免状态丢失是如果的重要。如果你只是在查找快速解决方法,下面是一些关于使用FragmentTransaction的建议,在日后的工作中牢记在心:

  • 在Activity生命周期方法提交事务要格外小心。绝大多数的应用在onCreate()方法的时候或者用户操作的时候就提交了事务,所以不会出现问题。但是,当你在Activity其他生命周期方法中调用事务,如onActivityResult()、onStart()和onResume()方法等,事情就变的不那么美好了。例如,你不应该在FragmentActivity#onResume()方法中提交事务,因为有时候这个方法会在Activity还原状态之前被调用(详情见文档)。如果你的应用真的需要在Activity生命周期非onCreate()方法中提交事务,请在FragmentActivity#onResumeFragments()或Activity#onPostResume()方法中提交。这两个方法会在Activity还原状态之后被调用,因此可以避免状态丢失(一个例子关于怎么使用,请看我对[这个问题的的答案](http://stackoverflow.com/questions/16265733/failure-delivering-result-onactivityforresult),里面提供了一些关于在Activity#onActivityResult()方式中提交FragmentTransaction的想法。)。

  • 在异步回调方法中避免调用事务。这里通常包括了像AsyncTask#onPostExceute()和LoaderManager.LoaderCallback#onLoadFinished()方法。在这里调用事务的问题在于当这些方法被调用时他们并不知道当前Activity生命周期状态。例如,考虑一下的步骤:

    1. 一个Activity启动了一个AsyncTask。

    2. 用户按下了Home键,导致这个Activity的onSaveInstanceState()和onStop()方法被调用。

    3. 这个AsyncTask完成了并且调用了onPostExecute()方法,而没有意识到这个Activity已经被Stopped。

    4. 在onPostExecute()方法中提交了一个FragmentTransaction,而导致抛出了一个异常。

    通常,避免这个异常最好的方法就是不要在所有的异步回调方法中提交事务。Google工程师好像也坚定这个信念。根据在Google Group上的关于Adnroid Developer的这篇博文,Android团队认为在异步回调方法中提交FragmentTransaction并转变UI是有损用户体验的。如果你应用需要在异步回调方法中调用事务,并且也没有简单的方法去确保回调方法不会在onSaveInstanceState()方法后调用,你只能用最不推荐的方法commitAllowingStateLoss(),你还要处理可能出现的状态丢失。(想要了解更多的这部分内容,请参考这个还有这个)

  • 最后再考虑使用commitAllowingStateLoss()方法。调用commit()和commitAllowingStateLoss()唯一的不同就是,当状态丢失发生后,后者不会抛出异常。一般你不想使用这个方法是因为它意味着状态丢失会有可能发生。当然,更好的解决方法就是让你应用一定要在Activity保存状态之前调用commit()方法,这就是更好的用户体验。出发状态丢失不能被避免,否则commitAllowingStateLoss()不应该被使用。

希望这些tips能够帮助你解决以前遇到的异常。如果你仍然还有问题,在StackOverflow上提一个问题并在评论中留下链接,我会去看一看的。:)

Linux Wireless之80211(nl80211, cfg80211, mac80211) Linux Wireless之80211(nl80211, cfg80211, mac80211)前言在Linux无线子系统中,cfg80211、mac80211和nl80211是三个关键的组件,它们共同工作以实现对802.11设备的配置和管理。cfg80211负责内核空间的通用API,mac80211负责具体的MAC层实现,而nl80211则作为用户空间与内核空间之间的桥梁,用于配置管理和通信。Netlink 是一个 Linux 中的 socket 类型,用于在内核与用户空间之间传递事件。 阅读详情

相关推荐

直流电源EMI滤波器设计实战:从器件选型到PCB布局的完整指南

本文提供了一份直流电源EMI滤波器的完整实战设计指南。针对EMI噪声超标问题,文章深入剖析了差模与共模噪声的抑制原理,详细讲解了从电路拓扑、核心器件(如X/Y电容、共模电感)的选型计算,到决定性能成败的PCB布局艺术。重点强调了低阻抗路径、干净接地及输入输出隔离等关键布局原则,并分享了常见的调试坑点与排查方法,旨在帮助硬件工程师设计出真正有效的滤波器,确保电源系统通过EMC测试。

q9r0s的博客 641

fragment使用经验(填过的坑)

0、 FragmentManager用于管理,获取frag,可通过id或者tag获取Fragment FragmentTransaction用于在容量里对frag进行增加,删除等操作,实现切换frag的效果 一、FragmentManager的事务执行是异步的,在commit之后只是表示提交,不是执行完成。如果前后两个事务有冲突,会报错。建议放在同一个事务中执行 二、F...

T的专栏 499

landsat8数据下载教程

下载landsat数据教程

weixin_44001203的博客 1万+

IllegalStateException: Can not perform this action after onSaveInstanceState

在使用Fragment是会遇到如下的Exception: IllegalStateException: Can not perform this action after onSaveInstanceState 导致这个异常的原因是:

进行式 1916

单细胞轨迹分析实战:基于Monocle和CytoTRACE的细胞分化潜能与状态解析

本文提供了基于Monocle和CytoTRACE的单细胞轨迹分析实战指南。通过乳腺癌数据集,详细演示了从数据准备、伪时序分析、细胞分化潜能评估到分支点功能挖掘的全流程。结合两种工具的优势,能有效解析细胞状态动态演变,为发育和疾病研究提供关键见解。

weixin_29070861的博客 478

Android逆向实战:用Xposed Hook微信消息发送(附完整代码)

本文提供了一份Android逆向实战指南,详细讲解如何使用Xposed框架Hook微信消息发送功能。内容涵盖环境搭建、逆向分析定位关键方法、编写Hook模块代码以及调试部署的全过程,并附有完整代码示例,帮助开发者深入理解Android应用底层交互与Hook技术。

weixin_29196315的博客 1118

IllegalStateException(java异常)

IllegalStateException是Java标准库中的一个异常类,通常表示在不合适或无效的情况下执行了某个方法或操作。IllegalStateException是Java标准库中的一个异常类,表示在不合适或无效的情况下执行了某个方法或操作。

weixin_55829616的博客 9150

为什么RingMo能成为遥感领域的首个生成式自监督基础模型?

RingMo作为遥感领域首个生成式自监督基础模型,通过创新的图像掩码建模技术解决了传统方法在遥感图像处理中的挑战。该模型利用两百万张多元数据集进行预训练,在小目标检测、场景分类等任务上表现卓越,显著提升了性能指标。RingMo的技术突破为遥感图像解译提供了高效解决方案,降低了标注成本并增强了模型泛化能力。

ll5678的博客 691

IllegalStateException(非法状态异常)可能的原因和解决方法

异常时,首先查看异常的详细信息以获取更多的上下文。仔细检查涉及到的对象状态、方法调用顺序、资源状态等,确保它们在当前的上下文和使用场景下是有效的。根据异常信息,逐步排查可能的原因,以便更好地理解和解决问题。异常时,仔细检查异常的堆栈跟踪和异常消息,以了解异常发生的具体位置和原因。然后,根据具体的情况调查可能的原因,并修改代码以确保对象的状态在调用方法时是合法的。表示在调用方法的当前对象的状态是不合法或不适当的。这种异常通常是由于方法的调用顺序不正确或对象状态与方法预期不符合引起的。

Java开源程序猿 9163

[LVGL] 刷新率优化

实验硬件:STM32F407ZGT6;2.4寸TFT-LCD模块(ILI9341驱动芯片、XTP2046触摸芯片)本文目标:lvgl的刷新率优化,解决拉帘子问题注意:本文在LVGL显示触摸代码移植完成的基础上进行,第一次使用lvgl可根据前文一步步移植,点击下方传送门查看相关文章传送门:STM32F4驱动ILI9341的TFT-LCD触摸屏(HAL库)(一)STM32F4驱动ILI9341的TFT-LCD触摸屏(HAL库)(二)[LVGL] 显示代码移植 基于STM32F4。

2301_77117901的博客 2784

lammps建模(电解液)opls-aa力场的基本流程

lammps建模(电解液)opls-aa力场的基本流程

syj0922的博客 2133

判断App处于前台还是后台工具包

用法 传入Context参数与想要判断是否位于前台的App的包名,会返回ture或者false表示App是否位于前台 //六种方法任选其一 //使用方法一 Boolean isForeground = BackgroundUtil.getRunningTask(context, packageName); //使用方法二 Boolean isForeground = BackgroundUtil.getRunningAppProcesses(context, packageName); //使用方法三

跟踪世界脚步 520

niushop靶场漏洞查找-文件上传漏洞等(超详细)

发现报错,而且这个报错十分熟悉,与我们所学的sqli报错注入特别像。这里查询到后面的url有且仅有一个,目测估计是后台。上传的图片是包含一句话木马的图片。发现获取到了webshell。实战漏洞-niushop。

qq_59020256的博客 1729

深入解析java.lang.IllegalStateException异常

是Java中的一个非受检异常,它表示在不适当的时间或状态下调用方法。日志记录工具:如Log4j、Logback等,可以记录异常信息和错误日志,方便排查和分析问题。断言工具:如Assert类,可以在程序中添加断言语句,用于验证代码中的假设条件是否满足,帮助我们在开发和测试阶段快速发现问题。异常处理框架:如Spring框架中的异常处理机制,可以统一处理应用程序中的异常,提供统一的异常处理逻辑和错误信息返回。异常是程序中常见的错误和异常情况,合理处理异常对于保证程序的正确性和稳定性非常重要。

博客 4万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

java基础避坑(十一)——IllegalStateException

IllegalStateException异常整理

shanheye的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

java.lang.IllegalStateException异常产生的原因及解决办法

异常一:java.lang.IllegalStateException:Cannot   forward   a   response   that   is   already   committed  异常二:IllegalStateException:response already commited  异常三:IllegalStateException:getOutputStream(

baokx的专栏 4万+

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

亲测有效,已解决java.lang.IllegalStateException异常的正确解决方法,嘿嘿嘿

出现 IllegalStateException 的原因可能有很多,但通常涉及以下几种情况: 对象状态不正确:例如,你可能尝试在一个没有初始化的对象上调用方法。 线程安全问题:多线程环境下,如果没有正确的同步,对象的状态可能会被破坏。 生命周期问题:在对象的生命周期中的某个不合适的时刻执行了某个操作。

PythonAigc的博客 1万+

已解决:java.lang.IllegalStateException 异常解决合集

异常通常表示对象当前的状态不符合要求。在处理这种异常时,需要检查操作的状态、资源的使用情况、事务的管理等。通过仔细分析异常信息,确保方法调用顺序正确,并在适当的状态下进行操作,可以有效解决此类问题。通过与开发者社区和团队的协作,可以快速找到问题的根本原因并提出解决方案。

猿鹏探码的博客 2672

JAVA_IllegalStateException(非法状态异常)

IllegalStateException: stream has already been operated upon or closed

weixin_45749407的博客 1262

已解决java.lang.IllegalStateException异常的正确解决方法,亲测有效!!!

通过认真的问题分析、细致的代码审查以及正确的问题修正方法,是可以被成功解决的。遵循良好的编程实践,如合理的状态管理和防御性编程,可以显著减少此类问题的发生。以上是此问题报错原因的解决方法,欢迎评论区留言讨论是否能解决,如果本文对你有帮助 欢迎关注、评论,博主才有动力持续记录遇到的问题!!!博主v:XiaoMing_Java嗨,大家好,我是小 明(小明java问道之路),

小明的Java问道之路 6万+

java.lang.IllegalStateException解决合集

1、跑monkey时报错,只定位到了是哪一个模块出的问题,但没有定位代码位置,大概是指Handler的问题因为没有定位到代码中的具体位置,所以我搜了一下网上的解决方案,google翻译给出的结果是:指定的同步屏障令牌尚未发布或已经被删除。大概是指Handler的问题。

luoro的博客 1万+

IllegalStateException解析

1. AsyncTask IllegalStateException最初的写法如下 if (asyncTask == null) { asyncTask = new MyAsyncTask(); } else { asyncTask.cancel(true); } asyncTask.execute();则在测试中偶现: java.lang.IllegalStateExc

awangyunke的专栏 4572

IllegalStateException 的解决办法

公司一个老项目,这两天爆出了一个问题。异常都是   java.lang.IllegalStateException: getOutputStream() has already been called for this response   这个项目的内容,就是通过页面下载一个word文件,当然这个word文件是根据用户的选择动态生成的。 当时实现这个功能的人,没有用servle...

SimonLei 2043
上一篇: Android修改输入法的回车键
下一篇: Volley get请求上传中文参数,后台接收到的是乱码的解决办法
Warkey_Song
博客等级 码龄14年 3粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值