首页 > 其他分享 >android异常:Can not p…

android异常:Can not p…

时间:2023-04-30 18:32:38浏览次数:43  
标签:ViewGroup java PhoneWindow dispatchKeyEvent Activity android 异常


本人某个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代码

android异常:Can not p…_android

 

android异常:Can not p…_java_02

android异常:Can <wbr>not <wbr>perform <wbr>this <wbr>action <wbr>after <wbr>onSaveInstanc

1. Can not perform this action after onSaveInstanceState   
2. android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)   
3. android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)   
4. android.app.Activity.onBackPressed(Activity.java:2066)   
5. android.app.Activity.onKeyUp(Activity.java:2044)   
6. android.view.KeyEvent.dispatch(KeyEvent.java:2529)   
7. android.app.Activity.dispatchKeyEvent(Activity.java:2274)   
8. com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)   
9. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
10. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
11. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
12. com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)   
13. com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)   
14. android.app.Activity.dispatchKeyEvent(Activity.java:2269)   
15. com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)   
16. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
17. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
18. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
19. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
20. android.widget.TabHost.dispatchKeyEvent(TabHost.java:297)   
21. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
22. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
23. android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)   
24. com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)   
25. com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)   
26. android.app.Activity.dispatchKeyEvent(Activity.java:2269)   
27. com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)   
28. android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2880)   
29. android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2853)   
30. android.view.ViewRoot.handleMessage(ViewRoot.java:2028)   
31. android.os.Handler.dispatchMessage(Handler.java:99)   
32. android.os.Looper.loop(Looper.java:132)   
33. android.app.ActivityThread.main(ActivityThread.java:4028)   
34. java.lang.reflect.Method.invokeNative(Native Method)   
35. java.lang.reflect.Method.invoke(Method.java:491)   
36. com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)   
37. com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)   
38. 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的一段原文:




Java代码

android异常:Can not p…_android

 

android异常:Can not p…_java_02

android异常:Can <wbr>not <wbr>perform <wbr>this <wbr>action <wbr>after <wbr>onSaveInstanc


1. 先看Application Fundamentals上的一段话:   
2.    
3.      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    
4. 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的效果。


标签:ViewGroup,java,PhoneWindow,dispatchKeyEvent,Activity,android,异常
From: https://blog.51cto.com/u_548275/6238010

相关文章

  • Android程序中像素(px)跟单位dp(di…
    publicclassUnitTransformUtil{publicstaticintdip2px(Contextcontext,floatdpValue){finalfloatscale=context.getResources().getDisplayMetrics().density;......
  • Android Paint和Color类
      setAntiAlias:设置画笔的锯齿效果。   setColor:设置画笔颜色   setARGB: 设置画笔的a,r,p,g值。   setAlpha: 设置Alpha值   setTextSize:设置字体尺寸。   setStyle: 设置画笔风格,空心或者实心。   setStrokeWidth:设置空心的边框......
  • Android 应用开发之(StrictM…
    最新的Android平台中(Android2.3起),新增加了一个新的类,叫StrictMode(android.os.StrictMode)。这个类可以用来帮助开发者改进他们编写的应用,并且提供了各种的策略,这些策略能随时检查和报告开发者开发应用中存在的问题,比如可以监视那些本不应该在主线程中完成的工作或者其他的一些......
  • Android裁剪图片为圆形图片
    以前在论坛中找过裁剪图片为圆形图片的方法,但是效果都不是很理想,这几天因为公司业务的要求,需要对头像进行裁剪以圆形的方式显示,这个方法是根据传入的图片的高度(height)和宽度(width)决定的,如果是width<=height时,则会裁剪高度,裁剪的区域是宽度不变高度从顶部到宽度width的长度;如果......
  • Android开发多线程断点续传下载器
    111Android开发多线程断点续传下载器分类: Android 2011-10-0123:14931人阅读 评论(8) 收藏 举报使用多线程断点续传下载器在下载的时候多个线程并发可以占用服务器端更多资源,从而加快下载速度,在下载过程中记录每个线程已拷贝数据的数......
  • android开发中使用GZIP压缩传输
    1.class=javaname="code">HTTP压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程HTML,CSS,Javascript,Text,它可以节省40%左右的流量。更为重要的是,它可以对动......
  • android有序广播和无序广播的区别
    BroadcastReceiver所对应的广播分两类:普通广播和有序广播。普通广播通过Context.sendBroadcast()方法来发送。它是完全异步的。所有的receivers接收器的执行顺序不确定。  因此,所有的receivers接收器接收broadcast的顺序不确定。这种方式效率更......
  • Android 检测是否有ROOT权限
    android(linux)很多命令需要root权限才能执行,比如说查看系统目录文件等,如果我们的程序需要用到查看此类文件或执行系统命令,就必须先获取Root权限。1.importjava.io.DataInputStream;2.importjava.io.DataOutputStream;3.importjava.io.InputStream;4.impor......
  • Android手机信息
    获取手机屏幕高度  1.privatevoidgetWeithAndHeight(){2.//这种方式在service中无法使用,3.DisplayMetricsdm=newDisplayMetrics();4.getWindowManager().getDefaultDisplay().getMetrics(dm);5.Stringw......
  • android平台下UITesting环境配置
    1.androidsdk至少需要android4.1,所以先通过SDKmanager更新sdk,我这里使用android4.22.eclipse至少需要3.6.2,否则不支持3.配置环境变量path,加入java,androidsdktool的路径4.通过AVDManager启动android4.2的虚拟机5.在虚拟机上安装需要测试的apk软件(下面的测试用例只测......