备用资源
备用资源是面向特定设备或运行时配置的那些资源,例如当前语言、特定屏幕大小或像素密度。 如果 Android 可以匹配比默认资源更特定于特定设备或配置的资源,则将改用该资源。 如果找不到与当前配置匹配的备用资源,则会加载默认资源。 下面的“资源位置”部分将更详细地介绍 Android 如何确定应用程序将使用的资源
备用资源将根据资源类型组织为 Resources 文件夹中的子目录,就像默认资源一样。 备用资源子目录的名称采用以下形式:ResourceType-限定符
限定符是用于标识特定设备配置的名称。 名称中可能有多个限定符,每个限定符都用短划线分隔。 例如,下面的屏幕截图显示了一个简单的项目,其中包含各种配置(例如区域设置、屏幕密度、屏幕大小和方向)的备用资源:
将限定符添加到资源类型时,适用以下规则:
可能有多个限定符,每个限定符用短划线分隔。
限定符可能只指定一次。
限定符必须按在下表中显示的顺序排列。
下面列出了可能的限定符以供参考:
MCC 和 MNC – 即移动国家/地区代码 (MCC) 和可选的移动网络代码 (MNC)。 SIM 卡将提供 MCC,而设备连接到的网络将提供 MNC。 虽然可以使用移动国家/地区代码来确定面向的区域设置,但建议的方法是使用下面指定的语言限定符。 例如,若要将资源设为面向德国,限定符将为
mcc262
。 若要将资源设为面向美国的 T-Mobile,限定符为mcc310-mnc026
。 有关移动国家/地区代码和移动网络代码的完整列表,请参阅 http://mcc-mnc.com/。语言 – 双字母 ISO 639-1 语言代码,且可选择后跟双字母 ISO-3166-alpha-2 区域代码。 如果同时提供这两个限定符,则它们由
-r
分隔。 例如,若要面向法语区域设置,则使用fr
限定符。 若要面向法国-加拿大区域设置,将使用fr-rCA
。 有关语言代码和区域代码的完整列表,请参阅表示语言名称的代码和国家/地区名称和码位元素。最小宽度 – 指定应用程序要用于执行的最小屏幕宽度。 为不同屏幕创建资源中对此进行了更详细的介绍。 在 API 级别 13(Android 3.2)及更级别本中可用。 例如,限定符
sw320dp
用于定位高度和宽度至少为 320dp 的设备。可用宽度 – wNdp 格式的屏幕最小宽度,其中 N 是以密度无关像素为单位的宽度。 当用户旋转设备时,此值可能会改变。 为不同屏幕创建资源中对此进行了更详细的介绍。 在 API 级别 13(Android 3.2)及更级别本中可用。 示例:限定符 w720dp 用于定位宽度至少为 720dp 的设备。
可用高度 – hNdp 格式的屏幕最小高度,其中 N 是以 dp 为单位的高度。 当用户旋转设备时,此值可能会改变。 为不同屏幕创建资源中对此进行了更详细的介绍。 在 API 级别 13(Android 3.2)及更级别本中可用。 例如,限定符 h720dp 用于定位高度至少为 720dp 的设备
屏幕大小 – 此限定符是这些资源所针对的屏幕大小的通用化。 为不同屏幕创建资源中对此进行了更详细的介绍。 可能值为
small
、normal
、large
和xlarge
。 已在 API 级别 9(Android 2.3/Android 2.3.1/Android 2.3.2)中添加屏幕纵横 – 该限定符将基于纵横比,而不是屏幕方向。 长屏将会更宽。 已在 API 级别 4 (Android 1.6) 中添加。 可能的值为 long 和 notlong。
屏幕方向 – 纵向或横向的屏幕方向。 这可能在应用程序的生存期内发生变化。 可能值为
port
和land
。基座模式 – 指定设备是采用车载基座还是桌面基座。 已在 API 级别 8 (Android 2.2.x) 中添加。 可能值为
car
和desk
。夜间模式 – 应用程序是在夜间还是白天运行。 这可能会在应用程序的生存期内发生改变,旨在让开发人员有机会在夜间使用较暗版本的界面。 已在 API 级别 8 (Android 2.2.x) 中添加。 可能值为
night
和notnight
。屏幕像素密度 (dpi) – 物理屏幕上给定区域中的像素数。 通常以每英寸点数 (dpi) 表示。 可能的值为:
ldpi
– 低密度屏幕。mdpi
– 中等密度屏幕hdpi
– 高密度屏幕xhdpi
– 超过高密度屏幕nodpi
– 不可缩放的资源tvdpi
– 在 API 级别 13(Android 3.2)中引入,针对 mdpi 和 hdpi 之间的屏幕。
触摸屏类型 – 指定设备可能具有的触摸屏类型。 可能的值为
notouch
(无触摸屏)、stylus
(适用于手写笔的电阻式触摸屏)和finger
(触摸屏)。键盘可用性 – 指定可用的键盘类型。 这可能会在应用程序的生存期内发生改变,例如当用户打开硬件键盘时。 可能的值为:
keysexposed
– 设备具有可用的键盘。 如果没有启用软件键盘,则仅当打开硬件键盘时才会使用该值。keyshidden
– 设备确实具有硬件键盘,但它处于隐藏状态,并且未启用软件键盘。keyssoft
– 设备启用了软件键盘。
主要文本输入法 – 用于指定可用于进行输入的硬件键类型。 可能的值为:
nokeys
– 没有可用于进行输入的硬件键。qwerty
– 有可用的 qwerty 键盘。12key
– 有 12 键的硬件键盘
导航键可用性 – 当五向或方向键导航可用时。 这可能在应用程序的生存期内发生变化。 可能的值为:
navexposed
– 导航键可供用户使用navhidden
– 导航键不可用。
主要非触摸导航方法 – 设备上可用的导航类型。 可能的值为:
nonav
– 唯一可用的导航设施是触摸屏dpad
– 方向键可用于导航trackball
– 设备具有用于导航的轨迹球wheel
– 存在一个或多个方向轮的不常见情况
平台版本(API 级别)– 设备支持的 vN 格式的 API 级别,其中 N 是所面向的 API 级别。 例如,v11 将面向 API 级别 11 (Android 3.0) 设备。
有关资源限定符的详细信息,请参阅 Android 开发人员网站上的提供资源。
Android 如何确定要使用的资源
Android 应用程序很可能包含许多资源。 了解 Android 如何在应用程序在设备上运行时为其选择资源非常重要。
Android 通过循环访问以下规则测试来确定资源基础:
消除矛盾限定符 – 例如,如果设备方向为竖屏,则所有横屏资源目录都将被拒绝。
忽略不支持的限定符 – 并非所有限定符都可用于所有 API 级别。 如果资源目录包含设备不支持的限定符,则将忽略该资源目录。
确定下一个优先级最高的限定符 – 参考上表选择下一个优先级最高的限定符(从上到下)。
保留限定符的所有资源目录 – 前提是有资源目录可将限定符与上表匹配。选择下一个优先级最高的限定符(从上到下)。
这些规则还在以下流程图中进行了说明:
当系统查找特定于密度的资源但找不到时,它将尝试查找其他特定于密度的资源并缩放这些资源。 Android 不一定使用默认资源。 例如,当查找低密度资源但其不可用时,Android 可能会选择高密度版本的资源,而不是默认或中等密度的资源。 这样做是因为高密度资源可以缩减二分之一(系数为 0.5),与缩减中等密度的资源(需要的系数为 0.75)相比,这样导致的可见性问题更少。
例如,请考虑具有以下可绘制资源目录的应用程序:
drawable
drawable-en
drawable-fr-rCA
drawable-en-port
drawable-en-notouch-12key
drawable-en-port-ldpi
drawable-port-ldpi
drawable-port-notouch-12key
现在,该应用程序在具有以下配置的设备上运行:
- 区域设置 – en-GB
- 方向 – port
- 屏幕密度 – hdpi
- 触摸屏类型 – notouch
- 主输入法 – 12key
首先,由于法语资源与 en-GB
的区域设置相冲突,因此法语资源被删除,留给我们的是:
drawable
drawable-en
drawable-en-port
drawable-en-notouch-12key
drawable-en-port-ldpi
drawable-port-ldpi
drawable-port-notouch-12key
接下来,从上面的限定符表中选择第一个限定符:MCC 和 MNC。 没有包含此限定符的资源目录,因此忽略 MCC/MNC 代码。
选择下一个限定符,即语言。 有与语言代码匹配的资源。 拒绝与语言代码 en
不匹配的所有资源目录,因此资源列表现在为:
drawable-en-port
drawable-en-notouch-12key
drawable-en-port-ldpi
存在的下一个限定符针对的是屏幕方向,因此将删除与屏幕方向 port
不匹配的所有资源目录:
drawable-en-port
drawable-en-port-ldpi
下一个是针对屏幕密度的限定符 ldpi
,这会导致再排除一个资源目录而得到以下结果:
drawable-en-port-ldpi
在此过程结束后,Android 将为设备使用资源目录 drawable-en-port-ldpi
中的可绘制资源。
注意
屏幕大小限定符对此选择过程提供了一个例外。 Android 可以选择适用于比当前设备的屏幕更小的屏幕的资源。 例如,大屏幕设备可以使用为普通大小的屏幕提供的资源。 但反之则不可以:同一个大屏幕设备不会使用为超大屏幕提供的资源。 如果 Android 找不到与给定屏幕大小匹配的资源集,应用程序将会崩溃。