Android开发 旋转屏幕导致Activity重建解决方法

 更新时间:2012年11月09日 17:09:36   作者:  
Android开发文档上专门有一小节解释这个问题。简单来说,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|keyboardHidden"
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无疑是最省事的。

相关文章

  • Android实现WebView删除缓存的方法

    Android实现WebView删除缓存的方法

    这篇文章主要介绍了Android实现WebView删除缓存的方法,实例分析了Android针对WebView操作缓存的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • Android studio 引用aar 进行java开发的操作步骤

    Android studio 引用aar 进行java开发的操作步骤

    这篇文章主要介绍了Android studio 引用aar 进行java开发的操作步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • 基于linux与windows平台下 如何下载android sdk源代码的方法详解

    基于linux与windows平台下 如何下载android sdk源代码的方法详解

    本文主要是介绍在linux和windows平台下,如何下载android sdk的源代码,注意是sdk的源代码,而不是android的所有源代码,同时介绍如何把sdk源代码加入到eclipse里,使android 平台手机开发者可以直接查看源代码,通过阅读SDK源码,能更好的理解和运用Android的API
    2013-05-05
  • 详解Flutter如何完全自定义TabBar

    详解Flutter如何完全自定义TabBar

    在App中TabBar形式交互是非常常见的,但是系统提供的的样式大多数又不能满足我们产品和UI的想法,本文记录了在Flutter中如何实现自定义TabBar的一个思路和过程,需要的可以参考一下
    2022-04-04
  • Android字符串和十六进制相互转化出现的中文乱码问题

    Android字符串和十六进制相互转化出现的中文乱码问题

    这篇文章主要介绍了Android字符串和十六进制相互转化出现的中文乱码问题的相关资料,需要的朋友可以参考下
    2016-02-02
  • Android中WebView图片实现自适应的方法

    Android中WebView图片实现自适应的方法

    这篇文章主要介绍了Android中WebView图片实现自适应的方法,涉及Android操作图片显示的相关技巧,需要的朋友可以参考下
    2015-05-05
  • Android自定义View实现随机数验证码

    Android自定义View实现随机数验证码

    这篇文章主要为大家详细介绍了Android如何利用自定义View实现随机数验证码效果,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-06-06
  • Android编程实现TCP客户端的方法

    Android编程实现TCP客户端的方法

    这篇文章主要介绍了Android编程实现TCP客户端的方法,结合实例形式分析了Android实现TCP客户端的原理及数据通信的相关技巧,需要的朋友可以参考下
    2016-04-04
  • Android布局优化之ViewStub控件

    Android布局优化之ViewStub控件

    ViewStub是一个非常轻量级的View,这篇文章主要为大家详细介绍了Android布局优化之ViewStub控件的使用方法以及注意事项,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Win10下Android App安装配置开发环境

    Win10下Android App安装配置开发环境

    这篇文章主要为大家详细介绍了Win10下Android App安装配置开发环境,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07

最新评论