解决方案


Android中按电源键锁屏然后旋转屏幕解锁这个时候onDestory会被调用以及屏幕旋转时也会被调用,打印消息如下:

09-01 09:27:30.900: D/TAG(27866): onCreate
09-01 09:30:50.600: D/TAG(27866): onDestroy
09-01 09:30:50.700: D/TAG(27866): onCreate
09-01 09:30:52.730: D/TAG(27866): onDestroy
09-01 09:30:52.850: D/TAG(27866): onCreate

那我们要怎么避免onDestory被调用到呢?答:我们只需要在AndroidManifest.xml中,设置Activity的android:configChanges=”keyboardHidden|orientation|screenSize”就可完美解决此问题。

<activity  
            android:name=".MainActivity"  
            android:configChanges="keyboardHidden|orientation|screenSize"  
            android:label="@string/app_name" >  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />  
                <category android:name="android.intent.category.LAUNCHER" />  
            </intent-filter>  
</activity>

android:screenOrientation的说明


Activity在屏幕当中显示的方向.属性值;可以是下表中列出的一个值:

"unspecified"

默认值,由系统来选择方向。它的使用策略,以及由于选择时特定的上下文环境,可能会因为设备的差异而不同。

"user"

使用用户当前首选的方向。

"behind"

使用Activity堆栈中与该Activity之下的那个Activity的相同的方向。

"landscape"

横向显示(宽度比高度要大)

"portrait"

纵向显示(高度比宽度要大)

"reverseLandscape"

与正常的横向方向相反显示,在API Level 9中被引入。

"reversePortrait"

与正常的纵向方向相反显示,在API Level 9中被引入。

"sensorLandscape"

横向显示,但是基于设备传感器,既可以是按正常方向显示,也可以反向显示,在API Level 9中被引入。

"sensorPortrait"

纵向显示,但是基于设备传感器,既可以是按正常方向显示,也可以反向显示,在API Level 9中被引入。

"sensor"

显示的方向是由设备的方向传感器来决定的。显示方向依赖与用户怎样持有设备;当用户旋转设备时,显示的方向会改变。但是,默认情况下,有些设备不会在所有的四个方向上都旋转,因此要允许在所有的四个方向上都能旋转,就要使用fullSensor属性值。

"fullSensor"

显示的方向(4个方向)是由设备的方向传感器来决定的,除了它允许屏幕有4个显示方向之外,其他与设置为“sensor”时情况类似,不管什么样的设备,通常都会这么做。例如,某些设备通常不使用纵向倒转或横向反转,但是使用这个设置,还是会发生这样的反转。这个值在API Level 9中引入。

"nosensor"

屏幕的显示方向不会参照物理方向传感器。传感器会被忽略,所以显示不会因用户移动设备而旋转。除了这个差别之外,系统会使用与“unspecified”设置相同的策略来旋转屏幕的方向。

注意:在给这个属性设置的值是“landscape”或portrait的时候,要考虑硬件对Activity运行的方向要求。正因如此,这些声明的值能够被诸如Google Play这样的服务所过滤,以便应用程序只能适用于那些支持Activity所要求的方向的设备。例如,如果声明了“landscape”、“reverseLandscape”、或“sensorLandscape”,那么应用程序就只能适用于那些支持横向显示的设备。但是,还应该使用<uses-feature>元素来明确的声明应用程序所有的屏幕方向是纵向的还是横行的。例如:<uses-feature android:name=”android.hardware.screen.portrait”/>。这个设置由Google Play提供的纯粹的过滤行为,并且在设备仅支持某个特定的方向时,平台本身并不控制应用程序是否能够被安装。

android:configChanges的说明


"mcc"

移动国家号码,由三位数字组成,每个国家都有自己独立的MCC,可以识别手机用户所属国家。

"mnc"

移动网号,在一个国家或者地区中,用于区分手机用户的服务商。

"locale"

所在地区发生变化。

"touchscreen"

触摸屏已经改变。(这不应该常发生。)

"keyboard"

键盘模式发生变化,例如:用户接入外部键盘输入。

"keyboardHidden"

用户打开手机硬件键盘。

"navigation"

导航型发生了变化。(这不应该常发生。)

"orientation"

设备旋转,横向显示和竖向显示模式切换。

"fontScale"

全局字体大小缩放发生改变

对Android:configChanges属性,一般认为有以下几点:
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

2、设置Activity的android:configChanges=”orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次

3、设置Activity的android:configChanges=”orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

但是,自从Android 3.2(API 13),在设置Activity的android:configChanges=”orientation|keyboardHidden”后,还是一样会重新调用各个生命周期的。因为screen size也开始跟着设备的横竖切换而改变。所以,在AndroidManifest.xml里设置的MiniSdkVersion和 TargetSdkVersion属性大于等于13的情况下,如果你想阻止程序在运行时重新加载Activity,除了设置”orientation”,你还必须设置”ScreenSize”。
解决方法:
AndroidManifest.xml中设置android:configChanges=”orientation|screenSize“

android:windowSoftInputMode的说明


"stateUnspecified"

软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置。

"stateUnchanged"

当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示。

"stateHidden"

用户选择activity时,软键盘总是被隐藏。

"stateAlwaysHidden"

当该Activity主窗口获取焦点时,软键盘也总是被隐藏的。

"keyboard"

键盘模式发生变化,例如:用户接入外部键盘输入。

"stateVisible"

软键盘通常是可见的。

"stateAlwaysVisible"

用户选择activity时,软键盘总是显示的状态。

"adjustUnspecified"

默认设置,通常由系统自行决定是隐藏还是显示。

"adjustResize"

该Activity总是调整屏幕的大小以便留出软键盘的空间。

"adjustPan"

当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。

通过配置windowSoftInputMode的属性值可以设置软键盘的不同显示方式,除了在AndroidManifest.xml中可以配置外,我们也可以在onCreate中的用代码实现,如下:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 
}

参考文章


android:screenOrientation的说明 固定屏幕显示方向
android:configChanges属性总结