当Android设备旋转(横竖屏切换)时,会导致某些设备配置的变化,从而导致Activity生命周期的变化。设备配置是用来描述设备当前状态的一系列特征,这些特征包括:屏幕的方向、屏幕的密度、屏幕的尺寸、键盘类型、底座模式以及语言等等。
为了更详细地了解Android横竖屏切换时Activity生命周期的变化,我们可以覆盖Activity的生命周期方法,在其中加入日志记录。代码如下:
public class MainActivity extends Activity {
private final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate() called!");
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart() called!");
}
@Override
public void onContentChanged() {
super.onContentChanged();
Log.d(TAG, "onConfigurationChanged() called!");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume() called!");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause() called!");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop() called!");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy() called!");
}
}
本人在真机系统Android4.2中运行该Activity,然后旋转设备完成横竖屏切换,得到测试结果如下:
默认情况下,无论是切换到横屏还是竖屏,Activity都会重新创建,从而重新执行一轮新的生命周期(从onPause到onResume)。
在这种情况下,由于Activity被重新创建,成员变量会被重新赋值,从而可能丢失存储在成员变量中的状态信息,导致界面重新被初始化,而不是保留在横竖屏切换前的状态。为了解决这个问题,一般有3种解决方案:
1.在AndroidManifest.xml的activity标签中,将android:screenOrientation属性强制设置为portrait(竖屏,默认值)或者landscape(横屏),来避免横竖屏切换
2.为横屏模式创建一个新的布局目录,命名为res/layout-land,然后在该目录下实现横屏模式下的布局。当横竖屏切换时,通过onSaveInstanceState(Bundle outState)方法来保存状态数据,切换完再取出该数据来恢复状态
3.在AndroidManifest.xml的activity标签中,配置android:configChanges属性,来设置Activity不被重新创建
显然,如果系统对于横竖屏的用户体验无要求,可以直接采用方案1。否则,可以采用方案2或者方案3,其中方案2适用于横竖屏布局差异较大的情况;方案3则更适用于横竖屏布局差异不大的情况。
对于方案3中提到的android:configChanges属性,一般常用的是orientation、keyboardHidden和screenSize。经本人在真机系统Android4.2中测试,在横竖屏切换时,有如下结论:
1.设置android:configChanges="orientation"时,Activity的生命周期变化与默认情况一样,都会重新创建。
2.设置android:configChanges="orientation|keyboardHidden"时,
2.1 若android:targetSdkVersion<=12,Activity不会重新创建;
2.2 若android:targetSdkVersion>12,Activity会重新创建。
3.设置android:configChanges="orientation|keyboardHidden|screenSize"时,Activity不会重新创建。