旋转屏幕导致Activity重建问题的解决办法
Android开发文档上专门有一小节解释这个问题。简单来说,Activity是负责与用户交互的最主要机制,任何“设置”(Configuration)的改变都可能对Activity的界面造成影响,这时系统会销毁并重建Activity以便反映新的Configuration。
“屏幕方向”(orientation)是一个Configuration,通过查看Configuration类的javadoc可以看到其他Configuration还有哪些:如fontScale、keyboardHidden和locale等等。
当屏幕旋转时,这个Configuration就发生了改变,因此当前显示的Activity需要被重建,Activity对象会被终止,它的onPause()、onStop()和onDestroy()方法依次触发,然后一个新的Activity对象被创建,onCreate()方法被触发。假设屏幕旋转前,用户正在手机上填写一个注册表单,如果处理不当,用户会发现旋转后的表单变成空白的了,严重影响使用体验。
要解决这个问题有三种方法:
方法1:禁止旋转屏幕
毫无疑问,这是最懒的办法了,相当于回避了本文提出的问题,方法如下看看就好:
<activity android:name=".MyActivity"
android:screenOrientation="portrait"
android:label="@string/app_name">
方法2:旋转后恢复现场
既然Activity会被销毁,那么我们就可以使用前文介绍过的“持久化/恢复现场”方法来解决。即在onPause()里将用户当前已经输入的内容保存到数据库或Preference,在onCreate()方法里读取并填充到表单中,这也是官方推荐的方法。
需要补充一点,如果Activity重建需要耗费大量资源或需要访问网络导致时间很长,可以实现onRetainNonConfigurationInstance()方法将所需数据先保存到一个对象里,像下面这样:
@Override
public Object onRetainNonConfigurationInstance() {
final MyDataObject data = collectMyLoadedData();
return data;
}
重建时,在onCreate()方法里通过getLastNonConfigurationInstance()方法获得之前保存的数据,如下所示:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();
if (data == null) {//表示不是由于Configuration改变触发的onCreate()
data = loadMyData();
}
...
}
方法3:手工处理旋转
一般情况下Configuration的改变会导致Activity被销毁重建,但也有办法让指定的Configuration改变时不重建Activity,方法是在AndroidManifest.xml里通过android:configChanges属性指定需要忽略的Configuration名字,例如下面这样:
<activity android:name=".MyActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard|screenLayout"
android:label="@string/app_name">
这样设置以后,当屏幕旋转时Activity对象不会被销毁——作为替代,Activity的onConfigurationChanged()方法被触发,在这里开发者可以获取到当前的屏幕方向以便做必要的更新。既然这种情况下的Activity不会被销毁,旋转后Activity里正显示的信息(例如文本框中的文字)也就不会丢失了。
假如你的应用里,横屏和竖屏使用同一个layout资源文件,onConfigurationChanged()里甚至可以什么都不做。但如果横屏与竖屏使用不同的layout资源文件,例如横屏用res/layout-land/main.xml,竖屏用res/layout-port/main.xml,则必须在onConfigurationChanged()里重新调用setContentView()方法以便新的layout能够生效,这时虽然Activity对象没有销毁,但界面上的各种控件都被销毁重建了,你需要写额外的代码来恢复界面信息。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig); // Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "横屏模式", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "竖屏模式", Toast.LENGTH_SHORT).show();
}
}
官方的Android开发文档不建议使用这种方式处理Configuration改变:
Note: Using this attribute should be avoided and used only as a last-resort. Please read Handling
Runtime Changes for more information about how to properly handle a restart due to a configuration change.
最佳实践
考虑到旋转屏幕并不是使Activity被销毁重建的唯一因素,仍然推荐前文介绍过的方法:在onPause()里持久化Activity状态,在onCreate()里恢复现场,可以做到一举多得;虽然Google不推荐设置android:configChanges属性的方式,但如果你的Activity横向纵向共用同一个layout文件,方法3无疑是最省事的。
参考资料:
Configuration
Changes
Handling
Runtime Changes
Activity
restart on rotation Android
How
to handle screen orientation change when progress dialog and background thread active?
本文地址:http://www.cnblogs.com/bjzhanghao/archive/2012/11/09/2761897.html
旋转屏幕导致Activity重建问题的解决办法的更多相关文章
- Android——旋转屏幕导致Activity重建解决方法
Android开发文档上专门有一小节解释这个问题.简单来说,Activity是负责与用户交互的最主要机制,任何“设置”(Configuration)的改变都可能对Activity的界面造成影响,这时系 ...
- Android开发 旋转屏幕导致Activity重建解决方法(转)
文章来源:http://www.jb51.net/article/31833.htm Android开发文档上专门有一小节解释这个问题.简单来说,Activity是负责与用户交互的最主要机制,任何“ ...
- 旋转屏幕导致Activity重建
简单来说,Activity是负责与用户交互的最主要机制,任何“设置”(Configuration)的改变都可能对Activity的界面造成影响,这时系统会销毁并重建Activity以便反映新的Conf ...
- Android使用Unity导致Activity被销毁的解决办法
由于需要在Android中使用Unity(Android的Activity会继承Unity提供的UnityPlayerActivity),可能是第三方的原因退出Unity后就导致Android整个应用 ...
- 记一次由于Java泛型类型擦除而导致的问题,及解决办法
中所周知,Java中的泛型并不像C++.C#一样是真正的泛型,其泛型是通过类型擦除来实现的.具体什么是类型擦除,可以参看这篇博文:http://icyfenix.iteye.com/blog/1021 ...
- 关于FusionCharts图表宽度width的设置问题导致图表显示异常的解决办法
关于FusionCharts图表宽度width的设置问题导致图表显示异常的解决办法 题设: 经常使用FusionCharts图表的朋友可能会遇到这个问题.就是在FusionCharts显示的时候有时候 ...
- Linux 改动inittab文件及忘记密码等导致无法进入系统的解决办法
改动inittab文件及忘记密码等导致无法进入系统的解决办法[摘] by:授客 QQ:1033553122 inittab是linux的系统启动模式配置文件,在”/etc“文件目录下没,其内容是: # ...
- MyEclipse格式化JSP代码导致Java表达式<%= %>自动换行的解决办法
MyEclipse格式化JSP代码导致Java表达式<%= %>自动换行的解决办法: 可以将Java表达式<%= %>换成EL表达式.
- 20190603 - CentOS 7 提示 Failed to load SELinux policy. Freezing 导致卡住不启动的解决办法
现象 最近 Windows 和两台 Mac 混用,将 Windows VirtualBox 中安装的 CentOS 7 拷贝到 Mac 上. 启动 CentOS 7 时,图形界面进度卡在最后,按 Es ...
随机推荐
- wamp环境的搭建
本文详细介绍了在Windows2003下使用Apache2.2.21/PHP5.3.5/Mysql5.5.19/phpMyAdmin3.4.9搭建php开发环境. 第一步:下载安装的文件 1. Apa ...
- 【WebSocket】WebSocket消息推送
准备使用WebSocket实现Java与Vue或者安卓间的实时通信,实现私密聊天.群聊.查询下资料备用. WebSocket客户端 websocket允许通过JavaScript建立与远程服务器的连接 ...
- vue.js循环语句
vue.js循环语句 循环使用 v-for 指令. v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组, site 是数组元素迭代的别名. v-for 可以 ...
- (转)docker-compose安装
转:https://blog.csdn.net/pushiqiang/article/details/78682323 https://blog.csdn.net/ericnany/article/d ...
- hbase centos7 安装体验
1. 准备需要jdk1.8,hbase安装文件.大家可以官网下载. 解压文件,复制到指定目录 tar -zxvf jdk-8u201-linux-x64.tar.gz tar -zxvf hbas ...
- 通过注册表修改IE的Internet选项
Internet Explorer 安全区域设置存储在以下注册表子项下面: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\I ...
- 开源 NAS 操作系统不完全汇总
市面上能见到的 NAS 操作系统很多,有如 FreeNAS 这样意气风发的开源免费版,也有完全商业的闭源版本,更有如黑群晖之类的破解版本.NAS 系统的迭代是一个大浪淘沙的过程,活下来的系统在功能上逐 ...
- Jenkins构建触发器的区别
Build periodically:定时进行项目构建或执行(它不care源码是否发生变化),配置如下: 0 2 * * * (每天2:00 必须build一次源码) 如果是要定时执行脚本,需要选择 ...
- QTP Code Segment
Dim WshShellset WshShell = CreateObject("WScript.Shell")WshShell.SendKeys "{DOWN}&quo ...
- [JSOI2016]无界单词
题目 题意:求\(\rm border\)长度为\(0\)的\(n\)位\(0,1\)字符串个数,并求字典序第\(k\)小的那一个. 首先是计数,正向不是很好算,考虑正难则反:设\(f_i\)表示长度 ...