Configuration源码解析
继承结构
Configuration维护了所有影响系统资源的信息,如地区、缩放、屏幕大小、 方向等
public final class Configuration implements Parcelable, Comparable<Configuration> {
}
域
- 静态空的Configuration,hide
- 字体缩放比例
- Mobile Country Code
- Mobile Network Code
- 国家/区域
- 用户设置国家,hide
public static final Configuration EMPTY = new Configuration();
public float fontScale;
public int mcc;
public int mnc;
public Locale locale;
public boolean userSetLocale;
常量
ScreenLayout相关
屏幕大小掩码、未设置、大于320x426、大于320x470、大于480x640、大于720x960
public static final int SCREENLAYOUT_SIZE_MASK = 0x0f;
public static final int SCREENLAYOUT_SIZE_UNDEFINED = 0x00;
public static final int SCREENLAYOUT_SIZE_SMALL = 0x01;
public static final int SCREENLAYOUT_SIZE_NORMAL = 0x02;
public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
横纵比掩码、未设置、不拉长、拉长
public static final int SCREENLAYOUT_LONG_MASK = 0x30;
public static final int SCREENLAYOUT_LONG_UNDEFINED = 0x00;
public static final int SCREENLAYOUT_LONG_NO = 0x10;
public static final int SCREENLAYOUT_LONG_YES = 0x20;
方向掩码、偏移量、未设置、从左到右、从右到左
public static final int SCREENLAYOUT_LAYOUTDIR_MASK = 0xC0;
public static final int SCREENLAYOUT_LAYOUTDIR_SHIFT = 6;
public static final int SCREENLAYOUT_LAYOUTDIR_UNDEFINED = 0x00;
public static final int SCREENLAYOUT_LAYOUTDIR_LTR = 0x01 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
public static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x02 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
屏幕大小-横纵比-方向都未设置、兼容模式用于特殊应用、实际值
public static final int SCREENLAYOUT_UNDEFINED = SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED | SCREENLAYOUT_LAYOUTDIR_UNDEFINED;
public static final int SCREENLAYOUT_COMPAT_NEEDED = 0x10000000;
public int screenLayout;
TouchScreen相关
未设置、不支持触屏、触控笔、手指触屏、实际值
public static final int TOUCHSCREEN_UNDEFINED = 0;
public static final int TOUCHSCREEN_NOTOUCH = 1;
@Deprecated public static final int TOUCHSCREEN_STYLUS = 2;
public static final int TOUCHSCREEN_FINGER = 3;
public int touchscreen;
Keyboard相关
未设置、无键盘、字母键盘、数字键盘、实际值
public static final int KEYBOARD_UNDEFINED = 0;
public static final int KEYBOARD_NOKEYS = 1;
public static final int KEYBOARD_QWERTY = 2;
public static final int KEYBOARD_12KEY = 3;
public int keyboard;
KeyboardHidden相关
未设置、显示键盘、隐藏键盘、隐藏软键盘、实际值
public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
public static final int HARDKEYBOARDHIDDEN_UNDEFINED = 0;
public static final int KEYBOARDHIDDEN_NO = 1;
public static final int HARDKEYBOARDHIDDEN_NO = 1;
public static final int KEYBOARDHIDDEN_YES = 2;
public static final int HARDKEYBOARDHIDDEN_YES = 2;
public static final int KEYBOARDHIDDEN_SOFT = 3;
public int keyboardHidden;
public int hardKeyboardHidden;
Navigation相关
未设置、无导航栏、键盘布局、轨迹球布局、车轮布局、实际值
public static final int NAVIGATION_UNDEFINED = 0;
public static final int NAVIGATION_NONAV = 1;
public static final int NAVIGATION_DPAD = 2;
public static final int NAVIGATION_TRACKBALL = 3;
public static final int NAVIGATION_WHEEL = 4;
public int navigation;
NavigationHidden相关
未设置、显示、隐藏、实际值
public static final int NAVIGATIONHIDDEN_UNDEFINED = 0;
public static final int NAVIGATIONHIDDEN_NO = 1;
public static final int NAVIGATIONHIDDEN_YES = 2;
public int navigationHidden;
Orientation相关
未设置、水平、垂直、正方形、实际值
public static final int ORIENTATION_UNDEFINED = 0;
public static final int ORIENTATION_PORTRAIT = 1;
public static final int ORIENTATION_LANDSCAPE = 2;
@Deprecated public static final int ORIENTATION_SQUARE = 3;
public int orientation;
UIMode相关
类型掩码、未设置、标准模式、桌面模式、车载模式、tv模式、应用模式
public static final int UI_MODE_TYPE_MASK = 0x0f;
public static final int UI_MODE_TYPE_UNDEFINED = 0x00;
public static final int UI_MODE_TYPE_NORMAL = 0x01;
public static final int UI_MODE_TYPE_DESK = 0x02;
public static final int UI_MODE_TYPE_CAR = 0x03;
public static final int UI_MODE_TYPE_TELEVISION = 0x04;
public static final int UI_MODE_TYPE_APPLIANCE = 0x05;
黑夜模式掩码、未设置、不启动黑夜模式、启动黑夜模式
public static final int UI_MODE_NIGHT_MASK = 0x30;
public static final int UI_MODE_NIGHT_UNDEFINED = 0x00;
public static final int UI_MODE_NIGHT_NO = 0x10;
public static final int UI_MODE_NIGHT_YES = 0x20;
public int uiMode;
Dp相关
未设置、可使用(最小)屏幕宽度/高度/密度实际值
public static final int SCREEN_WIDTH_DP_UNDEFINED = 0;
public int screenWidthDp;
public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0;
public int screenHeightDp;
public static final int SMALLEST_SCREEN_WIDTH_DP_UNDEFINED = 0;
public int smallestScreenWidthDp;
public static final int DENSITY_DPI_UNDEFINED = 0;
public int densityDpi;
compat相关
兼容模式下的宽度、高度、最小宽度、内部记录
public int compatScreenWidthDp;
public int compatScreenHeightDp;
public int compatSmallestScreenWidthDp;
public int seq;
方法
构造函数
public Configuration() {
setToDefaults();
}
public Configuration(Configuration o) {
setTo(o);
}
set方法
- 深拷贝传进来的参数
- 所有参数设为默认值
public void setTo(Configuration o) {
fontScale = o.fontScale;
mcc = o.mcc;
mnc = o.mnc;
if (o.locale != null) {
locale = (Locale) o.locale.clone();
}
userSetLocale = o.userSetLocale;
touchscreen = o.touchscreen;
keyboard = o.keyboard;
keyboardHidden = o.keyboardHidden;
hardKeyboardHidden = o.hardKeyboardHidden;
navigation = o.navigation;
navigationHidden = o.navigationHidden;
orientation = o.orientation;
screenLayout = o.screenLayout;
uiMode = o.uiMode;
screenWidthDp = o.screenWidthDp;
screenHeightDp = o.screenHeightDp;
smallestScreenWidthDp = o.smallestScreenWidthDp;
densityDpi = o.densityDpi;
compatScreenWidthDp = o.compatScreenWidthDp;
compatScreenHeightDp = o.compatScreenHeightDp;
compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
seq = o.seq;
}
public void setToDefaults() {
fontScale = 1;
mcc = mnc = 0;
locale = null;
userSetLocale = false;
touchscreen = TOUCHSCREEN_UNDEFINED;
keyboard = KEYBOARD_UNDEFINED;
keyboardHidden = KEYBOARDHIDDEN_UNDEFINED;
hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
navigation = NAVIGATION_UNDEFINED;
navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
orientation = ORIENTATION_UNDEFINED;
screenLayout = SCREENLAYOUT_UNDEFINED;
uiMode = UI_MODE_TYPE_UNDEFINED;
screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
densityDpi = DENSITY_DPI_UNDEFINED;
seq = 0;
}
@Deprecated public void makeDefault() {
setToDefaults();
}
设置国家、设置方向
public void setLocale(Locale loc) {
locale = loc;
userSetLocale = true;
setLayoutDirection(locale);
}
public void setLayoutDirection(Locale locale) {
final int layoutDirection = 1 + TextUtils.getLayoutDirectionFromLocale(locale);
screenLayout = (screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK)| (layoutDirection << SCREENLAYOUT_LAYOUTDIR_SHIFT);
}
get方法
获取方向、根据当前参数获取方向
public int getLayoutDirection() {
return ((screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) >> SCREENLAYOUT_LAYOUTDIR_SHIFT) - 1;
}
private static int getScreenLayoutNoDirection(int screenLayout) {
return screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK;
}
update方法
根据参数更新Configuration、判断是否需要更新资源
public int updateFrom(Configuration delta) {
int changed = 0;
if (delta.fontScale > 0 && fontScale != delta.fontScale) {
changed |= ActivityInfo.CONFIG_FONT_SCALE;
fontScale = delta.fontScale;
}
if (delta.mcc != 0 && mcc != delta.mcc) {
changed |= ActivityInfo.CONFIG_MCC;
mcc = delta.mcc;
}
if (delta.mnc != 0 && mnc != delta.mnc) {
changed |= ActivityInfo.CONFIG_MNC;
mnc = delta.mnc;
}
if (delta.locale != null && (locale == null || !locale.equals(delta.locale))) {
changed |= ActivityInfo.CONFIG_LOCALE;
locale = delta.locale != null? (Locale) delta.locale.clone() : null;
changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
setLayoutDirection(locale);
}
if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0))){
userSetLocale = true;
changed |= ActivityInfo.CONFIG_LOCALE;
}
if (delta.touchscreen != TOUCHSCREEN_UNDEFINED && touchscreen != delta.touchscreen) {
changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
touchscreen = delta.touchscreen;
}
if (delta.keyboard != KEYBOARD_UNDEFINED && keyboard != delta.keyboard) {
changed |= ActivityInfo.CONFIG_KEYBOARD;
keyboard = delta.keyboard;
}
if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED && keyboardHidden != delta.keyboardHidden) {
changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
keyboardHidden = delta.keyboardHidden;
}
if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED && hardKeyboardHidden != delta.hardKeyboardHidden) {
changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
hardKeyboardHidden = delta.hardKeyboardHidden;
}
if (delta.navigation != NAVIGATION_UNDEFINED && navigation != delta.navigation) {
changed |= ActivityInfo.CONFIG_NAVIGATION;
navigation = delta.navigation;
}
if (delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED && navigationHidden != delta.navigationHidden) {
changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
navigationHidden = delta.navigationHidden;
}
if (delta.orientation != ORIENTATION_UNDEFINED
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
orientation = delta.orientation;
}
if (getScreenLayoutNoDirection(delta.screenLayout) != (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED) && (getScreenLayoutNoDirection(screenLayout) != getScreenLayoutNoDirection(delta.screenLayout))) {
changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
if ((delta.screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) == 0) {
screenLayout = (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK)|delta.screenLayout;
} else {
screenLayout = delta.screenLayout;
}
}
if (delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED) && uiMode != delta.uiMode) {
changed |= ActivityInfo.CONFIG_UI_MODE;
if ((delta.uiMode&UI_MODE_TYPE_MASK) != UI_MODE_TYPE_UNDEFINED) {
uiMode = (uiMode&~UI_MODE_TYPE_MASK) | (delta.uiMode&UI_MODE_TYPE_MASK);
}
if ((delta.uiMode&UI_MODE_NIGHT_MASK) != UI_MODE_NIGHT_UNDEFINED) {
uiMode = (uiMode&~UI_MODE_NIGHT_MASK) | (delta.uiMode&UI_MODE_NIGHT_MASK);
}
}
if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED && screenWidthDp != delta.screenWidthDp) {
changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
screenWidthDp = delta.screenWidthDp;
}
if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED && screenHeightDp != delta.screenHeightDp) {
changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
screenHeightDp = delta.screenHeightDp;
}
if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
smallestScreenWidthDp = delta.smallestScreenWidthDp;
}
if (delta.densityDpi != DENSITY_DPI_UNDEFINED) {
changed |= ActivityInfo.CONFIG_DENSITY;
densityDpi = delta.densityDpi;
}
if (delta.compatScreenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) {
compatScreenWidthDp = delta.compatScreenWidthDp;
}
if (delta.compatScreenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
compatScreenHeightDp = delta.compatScreenHeightDp;
}
if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp;
}
if (delta.seq != 0) {
seq = delta.seq;
}
return changed;
}
public static boolean needNewResources(int configChanges, int interestingChanges) {
return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0;
}
diff方法
只对比Configuration差异,不修改
public int diff(Configuration delta) {
int changed = 0;
if (delta.fontScale > 0 && fontScale != delta.fontScale) {
changed |= ActivityInfo.CONFIG_FONT_SCALE;
}
if (delta.mcc != 0 && mcc != delta.mcc) {
changed |= ActivityInfo.CONFIG_MCC;
}
if (delta.mnc != 0 && mnc != delta.mnc) {
changed |= ActivityInfo.CONFIG_MNC;
}
if (delta.locale != null
&& (locale == null || !locale.equals(delta.locale))) {
changed |= ActivityInfo.CONFIG_LOCALE;
changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
}
if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
&& touchscreen != delta.touchscreen) {
changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
}
if (delta.keyboard != KEYBOARD_UNDEFINED
&& keyboard != delta.keyboard) {
changed |= ActivityInfo.CONFIG_KEYBOARD;
}
if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED
&& keyboardHidden != delta.keyboardHidden) {
changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
}
if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED
&& hardKeyboardHidden != delta.hardKeyboardHidden) {
changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
}
if (delta.navigation != NAVIGATION_UNDEFINED
&& navigation != delta.navigation) {
changed |= ActivityInfo.CONFIG_NAVIGATION;
}
if (delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED
&& navigationHidden != delta.navigationHidden) {
changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
}
if (delta.orientation != ORIENTATION_UNDEFINED
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
}
if (getScreenLayoutNoDirection(delta.screenLayout) !=
(SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED)
&& getScreenLayoutNoDirection(screenLayout) !=
getScreenLayoutNoDirection(delta.screenLayout)) {
changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
}
if (delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED)
&& uiMode != delta.uiMode) {
changed |= ActivityInfo.CONFIG_UI_MODE;
}
if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
&& screenWidthDp != delta.screenWidthDp) {
changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
}
if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED
&& screenHeightDp != delta.screenHeightDp) {
changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
}
if (delta.smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
&& smallestScreenWidthDp != delta.smallestScreenWidthDp) {
changed |= ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
}
if (delta.densityDpi != DENSITY_DPI_UNDEFINED
&& densityDpi != delta.densityDpi) {
changed |= ActivityInfo.CONFIG_DENSITY;
}
return changed;
}
ScreenLayout相关
- 根据传入数值设置屏幕,hide
- 根据传入的参数缩减屏幕,hide
- 检查当前屏幕是否达到指定大小
static public int resetScreenLayout(int curLayout) {
return (curLayout & ~(SCREENLAYOUT_LONG_MASK | SCREENLAYOUT_SIZE_MASK | SCREENLAYOUT_COMPAT_NEEDED)) | (SCREENLAYOUT_LONG_YES | SCREENLAYOUT_SIZE_XLARGE);
}
static public int reduceScreenLayout(int curLayout, int longSizeDp, int shortSizeDp) {
int screenLayoutSize;
boolean screenLayoutLong;
boolean screenLayoutCompatNeeded;
if (longSizeDp < 470) {
screenLayoutSize = SCREENLAYOUT_SIZE_SMALL;
screenLayoutLong = false;
screenLayoutCompatNeeded = false;
} else {
if (longSizeDp >= 960 && shortSizeDp >= 720) {
screenLayoutSize = SCREENLAYOUT_SIZE_XLARGE;
} else if (longSizeDp >= 640 && shortSizeDp >= 480) {
screenLayoutSize = SCREENLAYOUT_SIZE_LARGE;
} else {
screenLayoutSize = SCREENLAYOUT_SIZE_NORMAL;
}
if (shortSizeDp > 321 || longSizeDp > 570) {
screenLayoutCompatNeeded = true;
} else {
screenLayoutCompatNeeded = false;
}
if (((longSizeDp*3)/5) >= (shortSizeDp-1)) {
screenLayoutLong = true;
} else {
screenLayoutLong = false;
}
}
if (!screenLayoutLong) {
curLayout = (curLayout&~SCREENLAYOUT_LONG_MASK) | SCREENLAYOUT_LONG_NO;
}
if (screenLayoutCompatNeeded) {
curLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
}
int curSize = curLayout&SCREENLAYOUT_SIZE_MASK;
if (screenLayoutSize < curSize) {
curLayout = (curLayout&~SCREENLAYOUT_SIZE_MASK) | screenLayoutSize;
}
return curLayout;
}
public boolean isLayoutSizeAtLeast(int size) {
int cur = screenLayout&SCREENLAYOUT_SIZE_MASK;
if (cur == SCREENLAYOUT_SIZE_UNDEFINED) return false;
return cur >= size;
}
toString、Parcelable、compareTo、equals、hashCode方法
不赘述