Activity 自动销毁并调用 OnCreate()的原因分析_铽可喏_新浪博客

实验条件:

调试手机型号:GiONEE E3T

内核版本:3.4.5

Android版本:4.2.1

开发环境:Eclipse

 

实验内容:

Laucher Activity上的内容是一个ExpandableListView控件,该控件上有3个选项卡,第一个选项只有一个子项。在ExpandableListView的Adapter函数View getChildView(),解析一个带有EditText和Spinner的layout,并为他们分别添加编辑事件监听器和选项卡变化的监听器。

异常现象:

如果将AndroidManifest..xml中的Activity属性设成android:screenOrientation="landscape" ,每隔几分钟,界面突然退出,又重新生成,并且ExpandableListView的展开现象,如界面退出前的状态。但第一个选项的子项中的EditText和Spinner的内容恢复成默认初始值。EditView的内容不见,只有提示信息;Spinner的选项变成第一项;

原因分析:

现象反映的结果是界面重新生成,刷新为默认的初始状态。而界面生成,会调用函数OnCreate();在OnCreate()函数中,用Log.d()打印信息。发现每当上述异常现象发生,均会两次打印信息。说明确实调用了OnCreate()函数,并且调用了两次;

程序调用OnCreate()函数的原因目前知道的有两个,一个是StartAcitvity();一个是系统参数配置改变,如屏幕转屏、系统语言改变等,最有可能的是屏幕转屏;

整个应用程序中,只有一个Activity,且没有其他会调用该Activity的应用程序。则排除StartActivity()原因。

实验时,屏幕是平放在桌面,未人为改动系统的转向设置,但手机上设置/显示中的屏幕自动旋转功能是开启的。为排除该影响,将自动旋转功能关闭;重新下载程序,依然隔2分钟左右出现上述异常现象;

但不能排除有其他应用程序改变了屏幕的转向,手机上运行的有360安全卫士等程序;重载该Activity监听系统变化的事件onConfigurationChanged(Configuration newConfig),并在监听事件中打印出当前屏幕的转向信息。依然出现上述异常现象,两次OnCreate()中打印的信息中屏幕转向是在AndroidManifest.xml中配置的转向,说明初始生成的屏幕转向是没有问题的。

如果是因为屏幕转向改变而导致Activity重启,为何onConfigurationChanged()未打印信息?网上搜索可知,该事件监听函数的启用,需要在AndroidManifest..xml中有一定的配置。具体可参考http://blog.sina.com.cn/s/blog_8021d43b0101kzyc.html

由于在AndroidManifest..xml文件中,设置Activity的属性为水平;但是并没有layout-land文件夹,建立该文件夹,并将原来在layout中的文件拷贝到layout-land下。依然出现上述异常现象;

重载了Activity中的OnDestroy()函数,并用Log.d打印出信息;发现出现上述异常现象时,OnDestroy()被调用了两次,并且destroy时屏幕的转向确实曾被改变;LogCat打印出来的信息如下:

Activity <wbr>自动销毁并调用 <wbr>OnCreate()的原因分析

屏幕的转向确实曾被改变,导致Activity被销毁,后又重新生成;又因为某个配置被更改,再次被销毁、生成。

两次OnCreate()间隔在1s内,官方文档说,Android目标应用程序在API13及以上的时候,若屏幕方向改变,“screenSize”也会改变。因此,第二次Activity被销毁重启,有可能是screenSize引起的。

再次在OnDestroy()和OnCreate()中打印出信息,截图如下,第二次生成和销毁的长宽均是一样的,第二次销毁并不是由于screenSize引起的。


Activity <wbr>自动销毁并调用 <wbr>OnCreate()的原因分析

以上一个个参数查看的方式太过繁琐,在Configuration类的API中找到一个函数toString(),可将当前配置一个个转为String类型的:

Activity <wbr>自动销毁并调用 <wbr>OnCreate()的原因分析

发现屏幕的转向由水平被改为了垂直,然后调用了onDestroy(),之后系统调用了OnCreate()后,在系统配置没有改变的情况下,又调用了onDestroy(),随后游调用了OnCreate(),后面3次调用的系统配置是一样的。不明白为何系统配置没有改变的情况下,ACtivity依然重启?

网上也翻了很多网页、论坛、博客。不少人都出现OnCreate被调用2次的情况,最后的改法是在Acitvity的声明中增加属性android:configChanges="orientation|screenSize"。

 

重写onConfigurationChanged(),打印出每次监听到屏幕转向事件。发现几乎在同一时间,监测到屏幕的转向变为竖屏,然后从竖屏又变为横屏。从Acitvity的生命周期上看,是会调用两次销毁到重建的过程。
Activity <wbr>自动销毁并调用 <wbr>OnCreate()的原因分析

疑惑的是,不知道为何在上面打印出来的信息显示后面的3次调用,系统的配置没变。获取系统配置调用的是“this.getResources().getConfiguration()”;很多博客上也说,从横屏变为竖屏,OnCreate会执行两次。详细原因暂不知。

       在平板上运行同样的程序部出现该问题,在手机上运行就出现了。鉴于目前项目仅需要横屏显示,不需要屏幕的切换。详细原因等后面时间充裕,再仔细研究。




解决方法:

AndroidManifest..xml为Acitvity增加属性android:configChanges="orientation|screenSize”

 

心得:

以上的分析过程比较繁杂,而且基本是边怀疑边验证,一个观点肯定、否定后又肯定,往返循环。在于对Acitvity()的工作过程了解不够透彻。搜索博客、网页、论坛的同时。可回归介绍Activity的官方文档http://developer.android.com/reference/android/app/Activity.html。

 

参考:

http://www.eoeandroid.com/thread-79843-1-1.html

http://developer.android.com/reference/android/app/Activity.html

http://mahaile.blog.51cto.com/2891586/682676/

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值