旋转屏幕致使Activity重建

当屏幕旋转时,这个Configuration就发生了改变,所以当前显示的Activity须要被重建,Activity对象会被终止,它的onPause()、onStop()和onDestroy()方法依次触发,而后一个新的Activity对象被建立,onCreate()方法被触发。假设屏幕旋转前,用户正在手机上填写一个注册表单,若是处理不当,用户会发现旋转后的表单变成空白的了,严重影响使用体验。html

要解决这个问题有三种方法:android

方法1:禁止旋转屏幕

毫无疑问,这是最懒的办法了,至关于回避了本文提出的问题,方法以下看看就好:数据库

<activity android:name=".MyActivity"
          android:screenOrientation="portrait"
          android:label="@string/app_name">

 

方法2:旋转后恢复现场

既然Activity会被销毁,那么咱们就可使用前文介绍过的“持久化/恢复现场”方法来解决。即在onPause()里将用户当前已经输入的内容保存到数据库或Preference,在onCreate()方法里读取并填充到表单中,这也是官方推荐的方法。网络

须要补充一点,若是Activity重建须要耗费大量资源或须要访问网络致使时间很长,能够实现onRetainNonConfigurationInstance()方法将所需数据先保存到一个对象里,像下面这样:app

@Overridepublic Object onRetainNonConfigurationInstance() {    final MyDataObject data = collectMyLoadedData();    return data;
}

重建时,在onCreate()方法里经过getLastNonConfigurationInstance()方法得到以前保存的数据,以下所示:ide

@Overridepublic 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名字,例以下面这样:ui

<activity android:name=".MyActivity"
          android:configChanges="orientation|keyboardHidden"
          android:label="@string/app_name">

这样设置之后,当屏幕旋转时Activity对象不会被销毁——做为替代,Activity的onConfigurationChanged()方法被触发,在这里开发者能够获取到当前的屏幕方向以便作必要的更新。既然这种状况下的Activity不会被销毁,旋转后Activity里正显示的信息(例如文本框中的文字)也就不会丢失了。this

假如你的应用里,横屏和竖屏使用同一个layout资源文件,onConfigurationChanged()里甚至能够什么都不作。但若是横屏与竖屏使用不一样的layout资源文件,例如横屏用res/layout-land/main.xml,竖屏用res/layout-port/main.xml,则必须在onConfigurationChanged()里从新调用setContentView()方法以便新的layout可以生效,这时虽然Activity对象没有销毁,但界面上的各类控件都被销毁重建了,你须要写额外的代码来恢复界面信息。spa

@Overridepublic 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改变:rest

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

相关文章
相关标签/搜索