zoukankan      html  css  js  c++  java
  • android异常:Can not perform this action after onSaveInstanc

    extends:http://zhiweiofli.iteye.com/blog/1539467

    本人某个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的效果。

    重写各个tabview的onBackPressed,拦截Back键的事件,在里面直接调finish,然后通知父容器tabActivity执行finish,就可避开saveInstanceState的调用,试试吧
  • 相关阅读:
    【语言处理与Python】11.3数据采集
    【语言处理与Python】11.4使用XML\11.5使用Toolbox数据
    【语言处理与Python】11.1语料库结构:一个案例研究\11.2语料库生命周期
    【语言处理与Python】10.5段落语义层
    CentOS7.4 删除virbr0虚拟网卡
    套接字超时设置
    Linux命令进制转换、大小写转化
    网络编程第一卷读书笔记(随手记)
    linux下tcp选项TCP_DEFER_ACCEPT研究记录
    Cannot assign requested address出现的原因及解决方案
  • 原文地址:https://www.cnblogs.com/niray/p/4292748.html
Copyright © 2011-2022 走看看