Bootstrap

2021.08.29_Android_设备配置改变和Activity处理

Android设备那些配置会改变?

"mcc"  -  IMSI 移动国家/地区代码 (MCC) 发生了变化 - 检测到了 SIM 并更新了 MCC。

"mnc"  -  IMSI 移动网络代码 (MNC) 发生了变化 - 检测到了 SIM 并更新了 MNC。

"local"  -  语言区域发生了变化 — 用户为文本选择了新的显示语言。

"touchscreen"  -  触摸屏发生了变化。(这种情况通常永远不会发生。如是USB触摸屏的话还是会发生的)

"keyboard"  -  键盘类型发生了变化 — 例如,用户插入了一个外置键盘。

"keyboardHidden"  -  键盘无障碍功能发生了变化 — 例如,用户显示了硬件键盘。

"navigation"  -  导航类型(轨迹球/方向键)发生了变化。(这种情况通常永远不会发生。)

"screenLayout"  -  屏幕布局发生了变化 — 这可能是由激活了其他显示方式所致。

"fontScale"  -  字体缩放系数发生了变化 — 用户选择了新的全局字号。

"uiMode"  -  用户界面模式发生了变化 — 这可能是因用户将设备放入桌面/车载基座或夜间模式发生变化所致。 请参阅 UiModeManager。 此项为 API 级别 8 中新增配置。

"orientation"  -  屏幕方向发生了变化 — 用户旋转了设备。注:如果您的应用面向 API 级别 13 或更高级别(按照 minSdkVersion 和 targetSdkVersion 属性所声明的级别),则还应声明 "screenSize" 配置,因为当设备在横向与纵向之间切换时,该配置也会发生变化。

"screenSize"  -  当前可用屏幕尺寸发生了变化。它表示当前可用尺寸相对于当前纵横比的变化,因此会在用户在横向与纵向之间切换时发生变化。 不过,如果您的应用面向 API 级别 12 或更低级别,则 Activity 始终会自行处理此配置变更。此项为 API 级别 13 中新增配置。

"smallestScreenSize"  -  物理屏幕尺寸发生了变化。它表示与方向无关的尺寸变化,因此只有在实际物理屏幕尺寸发生变化(如切换到外部显示器)时才会变化。 对此配置的变更对应于smallestWidth 配置的变化。 不过,如果您的应用面向 API 级别 12 或更低级别,则 Activity 始终会自行处理此配置变更。此项为 API 级别 13 中新增配置。

"layoutDirection"  -  布局方向发生了变化。例如,从从左至右 (LTR) 更改为从右至左 (RTL)。 此项为 API 级别 17 中新增配置。

Android应用程序如何处理这种变化?

1.忽视这种变化,不做任何操作

         在AndroidManifest.xml文件中不指定参数androin:configChanges即可。配置改变时,Activity会被销毁,然后创新创建,再一次执行Activity生命周期处理。

2.Activity处理配置改变,不让Activity销毁

         在AndroidManifest.xml文件中指定参数androin:configChanges,用于捕获Android设备配置状态的改变,如androin:configChanges="locale|navigation|orientation", 有多项配置时添加分隔符 "|"。

如要禁止屏幕翻转,导致Activity销毁,可做如下操作

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

如果屏幕发生旋转,Activity不会销毁,但是会回调 onConfigurationChanged方法.

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}

注意:

1. 自从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“

2. 在实际测试过程中 navigation 属性是否添加对界面也存在一定影响,需要一并添加。我在开发过程中就有发现我拔插USB Keyboard设备时,配置了keyboard,还必须加上navigation才能够使Activity不重启。

;