`

android异常:Can not perform this action after onSaveInstanc

阅读更多

本人某个android项目开发阶段一直运行良好,直到上线前夕,在某款跑着android 4.03系统的手机运行却报出一下异常,导致force close:java.lang.IllegalStateException: Can not perform this action after onSaveInstance!


首先得了解一下我那项目的一些基本情况,UI结构是TabActivity包含着5个Tabs,每个tab又是一个独立的Activity。


异常是发生在android 4.03系统上,当我在某个Tab上按Back键时,就会报出java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState



从logout里发现了整个异常发生的过程:

 

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)
at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)
at android.app.Activity.onBackPressed(Activity.java:2066)
at android.app.Activity.onKeyUp(Activity.java:2044)
at android.view.KeyEvent.dispatch(KeyEvent.java:2529)
at android.app.Activity.dispatchKeyEvent(Activity.java:2274)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.widget.TabHost.dispatchKeyEvent(TabHost.java:297)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2880)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2853)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2028)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4028)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
 

上面的异常信息表示,我写的类不是异常的源头。根据异常信息Can not perform this action after onSaveInstanceState,可以了解到异常原因:在onSaveInstanceState行为之后,app执行某个不能响应的行为而导致异常发生。


在信息at android.app.Activity.onBackPressed(Activity.java:2066),这一句表明异常是在响应返回键响应事件的行为上发生的。我们顺藤摸瓜,考究一下在我们按下返回键时,activity会执行的响应:onKeyDown-->onBackPressed-->onPause->onStop->onDestroy。


那导火索onSaveInstanceState又是在什么时候执行的?


我们先看android API的一段原文:

 

先看Application Fundamentals上的一段话:
 
      Android calls onSaveInstanceState() before the activity becomes vulnerable to being destroyed by the system, but does not bother calling it when the instance is actually being destroyed by a user action 
(such as pressing the BACK key)

 


从上面可以知道,当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键的时候。


注意上面的双引号,何为“容易”?言下之意就是该activity还没有被销毁,而仅仅是一种可能性。


onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据。



那为什么项目里头响应onBackPressed事件时会报出上面的异常呢,还表明是after onSaveInstanceState?


原因是我Tab里面的Activity响应了onBackPressed事件,得弹出task,作为它的父容器TabActivity当然也得弹出task,TabActivity 变得“容易”被系统销毁,于是就调用onSaveInstanceState保存状态。


现在整个流程都明白了,可是,这一切都很正常啊,这个流程也很符合Activity的生命周期啊,为什么还会报异常呢?还是在最新的android 4.03上出问题,难道是说,系统不兼容?


对!


经过一番网上查阅,发现API 11 以上某些控件,包括 Fragment还有ActivityGroup,在调用saveInstanceState存在Bug,可能是google对saveInstanceState的实现做过修改。


直到隐藏在后面的原因,解决问题的思路就出来了:让父容器TabActivity在不调用saveInstanceState的情况下onDestroy


具体思路在tab上面的activity监听BACK键的事件,响应并拦截,再通过广播方式通知父容器TabActivity,主动销毁自己,达到原来响应onBackPressed退出App的效果。

 

 

1
0
分享到:
评论
16 楼 u010169720 2016-11-03  
而且fragment调用back也有不需要finish的时候呢,这个也要处理
15 楼 u010169720 2016-11-03  
我这里就是拦截的,但是还是报了这个
14 楼 Salijing 2016-05-05  
IT之冕 写道
我的方法是注释掉super.onBackPressed(),加上finish()
@Override
    public void onBackPressed() {
//      super.onBackPressed();
        finish();
    }

这招比较灵,哇咔咔咔咔咔
13 楼 wyyl1 2015-11-12  
大致意思是说我使用的 commit方法是在Activity的onSaveInstanceState()之后调用的,这样会出错,因为onSaveInstanceState
方法是在该Activity即将被销毁前调用,来保存Activity数据的,如果在保存玩状态后再给它添加Fragment就会出错。解决办法就
是把commit()方法替换成 commitAllowingStateLoss()就行了,其效果是一样的。

原文地址:http://blog.csdn.net/ranxiedao/article/details/8214936
12 楼 IT之冕 2015-09-01  
我的方法是注释掉super.onBackPressed(),加上finish()
@Override
    public void onBackPressed() {
//      super.onBackPressed();
        finish();
    }
11 楼 wqbs369 2015-06-17  
我的做法是在 fragment 的onDestroyView 方法中判断
if(!getActivity.isFinishing()){
屏蔽..到之前的.将当前的fragment从此fragment去除
getAcitivity().getSupportFramgnetManager.beginTransaction.remove(view).commit();
}
//view 为onCreateView中 inflate的view
10 楼 AlexTech 2014-08-30  
谢谢,解决了我大问题
9 楼 Tao_taobujue 2014-04-29  
lhy046510 写道
lz可以给个列子吗?谢谢

8 楼 芦茨法 2013-12-17  
芦茨法 写道
我也有碰到这个问题,我的解决方案是在父容器Activity与了Activity里加了个‘onSaveInstanceState()’方法内未加内容。可以解决问题

    补充:‘子’Activity不是‘了’Activity
7 楼 芦茨法 2013-12-17  
我也有碰到这个问题,我的解决方案是在父容器Activity与了Activity里加了个‘onSaveInstanceState()’方法内未加内容。可以解决问题
6 楼 zhiweiofli 2013-05-06  
pengqinping 写道
你这样是解决了按back,要是按Home和程序突然打断,会不会也有这种情况?

也不一定,saveInstanceState由系统控制着,系统觉得需要,还是会去调用的
5 楼 pengqinping 2013-04-27  
你这样是解决了按back,要是按Home和程序突然打断,会不会也有这种情况?
4 楼 zhiweiofli 2012-06-12  
lhy046510 写道
让父容器TabActivity在不调用saveInstanceState的情况下onDestroy
想实现这样的功能,有列子吗?lhy046510@163.com,感谢!




重写各个tabview的onBackPressed,拦截Back键的事件,在里面直接调finish,然后通知父容器tabActivity执行finish,就可避开saveInstanceState的调用,试试吧
3 楼 lhy046510 2012-06-11  
让父容器TabActivity在不调用saveInstanceState的情况下onDestroy
想实现这样的功能,有列子吗?lhy046510@163.com,感谢!



2 楼 zhiweiofli 2012-06-08  
lhy046510 写道
lz可以给个列子吗?谢谢

你需要怎样的例子呢?
1 楼 lhy046510 2012-06-07  
lz可以给个列子吗?谢谢

相关推荐

    action-buffer:提供了在处理后台任务时避免片段过渡期间出现 IllegalStateException 的示例

    这个存储库提供了一种在处理片段传输和后台任务时避免“java.lang.IllegalStateException:Can not perform this action after onSaveInstanceState”的方法。 您可以在的非常权威的阅读有关该问题和可能的解决方案...

    jlink 固件烧录指南

    ### J-LINK V8固件烧录指南 #### 一、引言 J-LINK是一款广泛应用于嵌入式系统开发的编程器与调试器,它能够帮助开发者完成代码的调试和固件的烧录工作。然而,在长时间使用过程中,由于各种原因可能会导致J-LINK...

    Android代码-Library

    Library: BibTeX on Android License: Library is free software published under the GNU GENERAL PUBLIC ...You can then perform a debug build by running $ ant debug You can now copy the resulting

    Android 6 Programming: Android Studio Development Guide

    The Code Editor provides programmers with an environment in which they can write their code, and perform some editing to it. The various features and functionalities provided by the Code Editor are ...

    Android之泡泡效果bubble

    .setCapabilities(AccessibilityServiceInfoCompat.CAPABILITY_CAN_PERFORM_GESTURES) .setPackageNames(packageName) .build() setServiceInfo(serviceInfo) ``` 以上就是如何在Android Studio 2022.3.1版本中...

    Could not perform operation -- unexpected exception. Unexpected failure (8000ff

    在尝试使用INTouch 2014 R2 SP1版本软件在Windows 10操作系统上创建新型应用程序时,用户遇到了“Could not perform operation -- unexpected exception. Unexpected failure (8000ffff)”这一错误提示。该问题出现...

    AndroidTest:android测试:打电话功能

    在Android应用开发中,打电话功能是一项常见的需求,尤其是在企业级应用或者个人通讯工具中。本文将深入探讨如何在Android平台上实现打电话功能,并结合Java编程语言进行详细讲解。 首先,我们需要了解的是Android...

    android浮动搜索框示例

    <action android:name="android.intent.action.SEARCH" /> android:name="android.app.searchable" android:resource="@xml/searchable" /> ``` 在`res/xml/searchable.xml`中定义搜索属性: ```xml ...

    java种菜源码-Sukrutha-PerformTask:Sukrutha-PerformTask

    Java种菜源码-Sukrutha-PerformTask是一个基于Java编程语言的开源项目,旨在为开发者提供一个实现任务执行的框架。Sukrutha-PerformTask项目的核心目标是帮助用户高效、可靠地管理一系列任务,使得在复杂的软件工程...

    android中自定义actionbar

    在Android应用开发中,Action Bar是用户界面的一个关键组件,它位于屏幕顶部,提供应用程序的标识、主要操作以及导航选项。然而,系统默认的Action Bar可能无法满足所有设计需求,因此开发者经常需要对其进行自定义...

    android软键盘上添加一个按钮

    <action android:name="android.view.InputMethod" /> android:name="android.inputmethodservice" android:resource="@xml/input_method_metadata" /> ``` 至此,我们已经完成了自定义软键盘的创建,包括...

    android Accessibility无障碍服务实现获取系统全局任何控件的名称和坐标信息

    通过调用 AccessibilityNodeInfo 的 `performAction(int action)` 方法,我们可以模拟用户对控件的操作,例如 ACTION_CLICK 或 ACTION_SCROLL_DOWN。 在实际开发中,需要注意的是,由于无障碍服务涉及到用户的隐私...

    j-link v9 修复

    **J-Link V9 固件修复指南** J-Link 是 SEGGER 公司推出的一款广受欢迎的仿真器和编程器,它支持多种微控制器和嵌入式系统,为开发者提供方便的调试环境。J-Link V9 是该系列的一个版本,可能会遇到需要修复固件的...

    Delphi ActionList详解

    1. **Caption**:Action的显示文本。 2. **Category**:分类,用于组织Action,方便管理和查找。 3. **Checked**:选中状态,适用于复选框型Action。 4. **Enabled**:表示Action当前是否可用。 5. **HelpContext**...

    Decompiling Android.pdf

    1. **Chapter 3: Inside the DEX File** - This chapter delves into the structure and contents of DEX files, providing insights into how decompilers can extract meaningful information from them. ...

    计算器android教学或实训文档

    ### 计算器Android教学实训知识点 #### 一、项目概述 本实训文档旨在通过一个简单的计算器应用开发,帮助学习者掌握Android应用的基本开发流程和技术要点。计算器应用不仅能够加深对Android开发的理解,还能锻炼...

    微信小程序控制台提示warning:Now you can provide attr "wx:key" for a "wx:for" to improve performance解决方法

    主要介绍了微信小程序控制台提示warning:Now you can provide attr "wx:key" for a "wx:for" to improve performance解决方法,简单分析了wx:for警告提示相关解决方法,需要的朋友可以参考下

    DBIx::Perform char term-based DB utility-开源

    DBIx :: Informix :: Perform是Informix Perform查询和更新实用程序的基于Perl和Curses的跨数据库模拟器。 它可以使用现有的执行描述文件,也可以查询数据库的表模式。

Global site tag (gtag.js) - Google Analytics