安卓横竖屏切换注意事项
2018-07-23 本文已影响0人
menteelin
最近在做项目时有用户反馈开启屏幕自动旋转功能后偶尔会崩溃,当时一脸懵逼,因为给客户提供的Module在Activity中已经调用了setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
方法来固定屏幕方向。但确实出现了崩溃,报错信息如下:
java.lang.IllegalStateException: Activity has been destroyed
出现了问题不能怪手机也不能怪电脑,自己老老实实的找bug。经过一番捣鼓发现了问题的原因,写篇文章分享一下,以防有人继续采坑。
实例验证
我们通过一个例子来验证这个问题,新建一个工程包括MainActivity和Main2Activity,可以在MainActivity中点击按钮进入Main2Activity。Main2Activity我们在其onCreate()方法中调用
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
方法,固定屏幕方向。开启手机屏幕“自动旋转”功能,下面来打印两种场景下的日志。
- MainActivity竖屏下进入Main2Activity
07-23 11:46:31.407 5035-5035/com.jrmf360.screenrotation E/MainActivity: onPause
07-23 11:46:31.423 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onCreate:portrail
07-23 11:46:31.445 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onStart
07-23 11:46:31.445 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onResume
07-23 11:46:31.886 5035-5035/com.jrmf360.screenrotation E/MainActivity: onStop
可以看到Main2Activity生命周期正常,没有销毁重建。
- MainActivity横屏下进入Main2Activity
07-23 11:47:55.004 5035-5035/com.jrmf360.screenrotation E/MainActivity: onPause
07-23 11:47:55.018 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onCreate:landscape
07-23 11:47:55.126 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onStart
07-23 11:47:55.126 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onResume
07-23 11:47:55.161 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onPause
07-23 11:47:55.161 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onStop
07-23 11:47:55.161 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onDestroy
07-23 11:47:55.178 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onCreate:portrail
07-23 11:47:55.201 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onStart
07-23 11:47:55.201 5035-5035/com.jrmf360.screenrotation E/Main2Activity--->: onResume
07-23 11:47:55.277 5035-5035/com.jrmf360.screenrotation E/MainActivity: onStop
可以看到Main2Activity第一次创建是横屏(landscape),然后销毁,接着重建竖屏(portrail),这就是为什么会报错Activity has been destroyed
的原因。不管在onCreate方法中设置的屏幕方向是什么,进入Activity时,会先按照当前屏幕的方向创建Activity,如果设置的屏幕方向给当前屏幕方向不一致,销毁重建。
解决方案
针对上述问题有两种解决方案
- 不要通过代码设置屏幕方向,在Manifest.xml文件中添加
android:screenOrientation="portrait"
设置,这样进入Activity会直接按照此设置的屏幕方向创建Activity - 在Manifest.xml文件中添加如下设置
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
这样当屏幕旋转时,Activity不会销毁重建,会调用
public void onConfigurationChanged(Configuration newConfig)
方法。这种设置下,支持屏幕可以横竖屏切换,但是要注意布局适配横竖屏UI。
总结:屏幕旋转可以选择固定屏幕方向,在Manifest.xml文件中固定,不要使用代码;也可以选择支持横竖屏切换,需要做UI适配。