在上一篇中我们简单了解关于Android中状态保存的过程和原理,这一篇中我们来看一下在系统配置改变的情况下保存数据及恢复数据的过程。
下面我们先来看一个现象:(代码在 Android中状态保存探究(上)中)
先启动应用如下:
打印的Log
再翻转屏幕
打印的Log如下
可以看到每翻转一次屏幕实际上系统会停止原理的activity并销毁然后重新启动一次,在这个过程中会调用onSaveInstanceState方法来保存原来的数据并通过onCreate方法恢复数据。因为要先onDestroy然后才onCreate,所以就会出现一个黑屏(闪屏)的短暂过程。像这种改变整个系统配置的现象叫做ConfigurationChanges.
ConfigurationChange具体有哪些,都代表什么,请看:http://developer.android.com/reference/android/R.attr.html#configChanges
Constant | Value | Description |
---|---|---|
mcc |
0x0001 | The IMSI MCC has changed, that is a SIM has been detected and updated the Mobile Country Code. |
mnc |
0x0002 | The IMSI MNC has changed, that is a SIM has been detected and updated the Mobile Network Code. |
locale |
0x0004 | The locale has changed, that is the user has selected a new language that text should be displayed in. |
touchscreen |
0x0008 | The touchscreen has changed. Should never normally happen. |
keyboard |
0x0010 | The keyboard type has changed, for example the user has plugged in an external keyboard. |
keyboardHidden |
0x0020 | The keyboard or navigation accessibility has changed, for example the user has slid the keyboard out to expose it. Note that despite its name, this applied to any accessibility: keyboard or navigation.键盘隐藏 |
navigation |
0x0040 | The navigation type has changed. Should never normally happen.导航 |
orientation |
0x0080 | The screen orientation has changed, that is the user has rotated the device.屏幕翻转 |
screenLayout |
0x0100 | The screen layout has changed. This might be caused by a different display being activated.屏幕布局改变 |
uiMode |
0x0200 | The global user interface mode has changed. For example, going in or out of car mode, night mode changing, etc. |
screenSize |
0x0400 | The current available screen size has changed. If applications don‘t target at least HONEYCOMB_MR2 then the activity will always handle this itself (the change will not result in a restart). This represents a change in the currently available size, so will change when the user switches between landscape and portrait. |
smallestScreenSize |
0x0800 | The physical screen size has changed. If applications don‘t target at least HONEYCOMB_MR2 then the activity will always handle this itself (the change will not result in a restart). This represents a change in size regardless of orientation, so will only change when the actual physical screen size has changed such as switching to an external display. |
layoutDirection |
0x2000 | The layout direction has changed. For example going from LTR to RTL. |
fontScale |
0x40000000 | The font scaling factor has changed, that is the user has selected a new global font size.字体大小 |
有时候我们需要在配置改变的时候恢复一些不能够序列化的对象,这时候就需要用onRetainNonConfigurationInstance方法保存,然后在onCreate方法中通过getLastNonConfigurationInstance获取对象。但是要注意的是,保存的对象不要用与context关联的对象,比如View,否则会引起内存泄露。
有没有什么方法在Configuration改变的时候不重新启动Activity,在manifest文件中我们来看一下一个配置:
好吧,先配上orientation值,我们再去Activity中添加一段代码,如下:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Log.i("大碗干拌", "调用了onConfiguration onChanged方法"); if(newConfig.equals(Configuration.ORIENTATION_LANDSCAPE)){ Log.i("大碗干拌", "切换到了横屏"); }else if(newConfig.equals(Configuration.ORIENTATION_PORTRAIT)){ Log.i("大碗干拌", "切换到了竖屏"); } }这个时候切换屏幕时系统会调用onConfigurationChanged方法,来处理我们自定义的配置改变。而不会去重新启动新的Activity。