实验条件:
调试手机型号: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被销毁,后又重新生成;又因为某个配置被更改,再次被销毁、生成。
两次OnCreate()间隔在1s内,官方文档说,Android目标应用程序在API13及以上的时候,若屏幕方向改变,“screenSize”也会改变。因此,第二次Activity被销毁重启,有可能是screenSize引起的。
再次在OnDestroy()和OnCreate()中打印出信息,截图如下,第二次生成和销毁的长宽均是一样的,第二次销毁并不是由于screenSize引起的。
发现屏幕的转向由水平被改为了垂直,然后调用了onDestroy(),之后系统调用了OnCreate()后,在系统配置没有改变的情况下,又调用了onDestroy(),随后游调用了OnCreate(),后面3次调用的系统配置是一样的。不明白为何系统配置没有改变的情况下,ACtivity依然重启?
网上也翻了很多网页、论坛、博客。不少人都出现OnCreate被调用2次的情况,最后的改法是在Acitvity的声明中增加属性android:configChanges="orientation|screenSize"。
疑惑的是,不知道为何在上面打印出来的信息显示后面的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/