语言和语言区域解析概览
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
从 Android 7.0(API 级别 24)开始,Android 为多语言用户提供增强型支持服务,让他们可以在设置中选择多个语言区域。Android 通过大幅扩展受支持的语言区域数量并更改系统解析资源的方式来提供此功能。
本文档首先说明低于 7.0(API 级别 24)的 Android 版本中的资源解析策略,接着介绍 Android 7.0 中改进的资源解析策略,最后说明如何充分利用更多语言区域来支持更多的多语言用户。
解析语言资源所面临的挑战
在 Android 7.0 之前,Android 并非始终能成功匹配应用和系统语言区域。
例如,假设您遇到了以下情况:
- 您的应用的默认语言为
en_US
(美式英语),但它也在 es_ES
资源文件中对西班牙字符串进行了本地化。
- 将设备设置为
es_MX
当您的 Java 代码引用字符串时,系统会从默认 (en_US
) 资源文件加载字符串,即使应用在 es_ES
下有本地化的西班牙语资源。这是因为当系统无法找到精确匹配时,它会继续通过将国家/地区代码从语言区域中剥离来查找资源。最后,如果未找到匹配,系统会恢复为默认模式,即 en_US
。
如果用户选择应用根本不支持的语言(如法语),则系统也会默认显示 en_US
。例如:
表 1. 没有精确语言区域匹配项的资源解析。
用户设置 |
应用资源 |
资源解析 |
fr_CH |
默认值 (en)
de_DE
es_ES
fr_FR
it_IT
|
尝试 fr_CH => 失败
尝试 fr => 失败
使用默认值 (en) |
在此示例中,系统在不知道用户是否理解英语的情况下显示英语字符串。目前,此行为很常见。
对资源解析策略的改进
Android 7.0(API 级别 24)可提供更稳健的资源解析,并自动查找更好的备用方法。不过,为了加速解析和提升可维护性,您应以最常用的母语存储资源。例如,如果您之前将西班牙语资源存储在 values-es-rUS
目录中,请将其移至包含拉丁美洲西班牙语的 values-b+es+419
目录中。同样,如果您在名为 values-en-rGB
的目录中存储有资源字符串,请将此目录重命名为 values-b+en+001
(国际英语),因为 en-GB
字符串的最常用母语为 en-001
。以下示例介绍为何这些做法可提升资源解析的性能和可靠性。
资源解析示例
使用 7.0 以上的 Android 版本时,以不同的方式解析表 1 中所描述的案例:
表 2. 针对没有精确语言区域匹配项时改进的资源解析策略。
用户设置 |
应用资源 |
资源解析 |
- fr_CH
|
默认值 (en)
de_DE
es_ES
fr_FR
it_IT
|
尝试 fr_CH => 失败
尝试 fr => 失败
尝试 fr 的子项 => fr_FR
使用 fr_FR
|
现在,用户获得的是法语资源而不是英语。此示例还表明对于 Android 7.0 或更高版本,您为什么应将法语字符串存储在 fr
(而非 fr_FR
)中。此处的操作是匹配最接近的母语,从而使解析更快速且更具预见性。
除了这个改进的解析逻辑外,Android 现在还提供更多的用户语言以供选择。下面,我们将意大利语指定为附加用户语言,但假设应用不支持法语,再次尝试上面的示例。
表 3. 应用仅与用户的次优语言区域设置匹配时的资源解析。
用户设置 |
应用资源 |
资源解析 |
- fr_CH
- it_CH
|
默认值 (en)
de_DE
es_ES
it_IT
|
尝试 fr_CH => 失败
尝试 fr => 失败
尝试 fr 的子项 => 失败
尝试 it_CH => 失败
尝试 it => 失败
尝试 it 的子项 => it_IT
使用 it_IT
|
即使应用不支持法语,用户仍可使用自己所能理解的语言。
设计应用以支持其他语言区域
Android 提供的一些工具可让您更轻松地将应用内容本地化,通过语言偏好吸引用户。建议您使用以下方法来配置应用,使其能够以可扩展的方式适应不同的语言和格式规范。
指定您的应用支持哪些语言
为确保正确解析语言,请在模块级 build.gradle
文件中使用 resConfigs
属性指定您的应用支持哪些语言。
以下代码示例为如何使用 resConfigs
表示支持哪些语言。在此示例中,应用既支持英语,也支持西班牙语。
Groovy
android {
defaultConfig {
...
resConfigs "en", "es"
}
}
Kotlin
android {
defaultConfig {
...
resConfigs("en", "es")
}
}
由于构建系统合并应用及其依赖项资源的方式,您必须以这种方式指定支持哪些语言,以确保正确响应用户的语言设置。
LocaleList API
从 Android 7.0(API 级别 24)开始,Android 显示的 LocaleList.getDefault()
API 可让应用直接查询用户已指定的语言列表。您可以使用此 API 创建更成熟的应用行为和更优化的内容显示。例如,搜索可以基于用户的设置以多种语言显示结果。浏览器应用可避免翻译以用户理解的语言显示的页面,键盘应用可自动启用所有适用的布局。
直到 Android 6.0(API 级别 23),Android 仅支持许多常用语言(en、es、ar、fr、ru)的一个或两个语言区域。由于每种语言只有几种变体,因此,应用可以通过在资源文件中将一些数字和日期存储为硬编码字符串解决此问题。不过,随着 Android 扩展了支持的语言区域集,即使在一个语言区域中,日期、时间、货币及类似信息也会存在显著差异。对您的格式进行硬编码会让最终用户困惑不已。因此,在针对 Android 7.0 或更高版本开发应用时,请务必使用格式化程序代替硬编码数字和日期字符串。
例如,Android 7.0 和更高版本支持 27 个阿拉伯语言区域。这些语言区域可以共享大多数资源,但其中一些资源首选 ASCII 数字,另一些则首选本地数字。例如,如果您想要创建一个具有数字变量的句子,如“Choose a 4 digit pin”,则按如下所示使用格式化程序:
format(locale, "Choose a %d-digit PIN", 4)
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Language and locale resolution overview\n\nStarting in Android 7.0 (API level 24),\nAndroid provides enhanced support for multilingual users,\nallowing them to select multiple locales in settings. Android\nprovides this capability by greatly expanding the number of locales supported\nand changing the way the system resolves resources.\n\nThis document starts by explaining the resource resolution strategy in\nversions of Android lower than 7.0 (API level 24). Next, it describes\nthe improved resource resolution strategy in Android 7.0.\nLast, it explains how to take advantage of\nthe expanded number of locales to support more multilingual users.\n\nChallenges in resolving language resources\n------------------------------------------\n\nPrior to Android 7.0, Android could not always successfully\nmatch app and system locales.\n\nFor example, assume that you have the following situation:\n\n- Your app's default language is `en_US` (US English), and it also has Spanish strings localized in `es_ES` resource files.\n- A device is set to `es_MX`\n\nWhen your Java code refers to strings, the system would load\nstrings from the default (`en_US`) resource file, even if the app has\nSpanish resources localized under `es_ES`. This is because when the system\ncannot find an exact match, it continues to look for resources by stripping the\ncountry code off the locale. Finally, if no match is found, the system falls\nback to the default, which is `en_US`.\n\nThe system would also default to `en_US` if the user chose a language that\nthe app didn't support at all, like French. For example:\n\n\n**Table 1.** Resource resolution without an exact locale match.\n\n| User Settings | App Resources | Resource Resolution |\n|---------------|--------------------------------------|-----------------------------------------------------|\n| fr_CH | default (en) de_DE es_ES fr_FR it_IT | Try fr_CH =\\\u003e Fail Try fr =\\\u003e Fail Use default (en) |\n\nIn this example, the system displays English strings without\nknowing whether the user can understand English. This behavior is pretty common\ntoday.\n\nImprovements to resource-resolution strategy\n--------------------------------------------\n\nAndroid 7.0 (API level 24) brings more robust resource resolution, and\nfinds better fallbacks automatically.\nHowever, to speed up resolution and improve\nmaintainability, you should store resources in the most common parent dialect.\nFor example, if you were storing Spanish resources\nin the `values-es-rUS` directory\nbefore, move them into the `values-b+es+419` directory,\nwhich contains Latin American Spanish.\nSimilarly, if you have resource strings in a\ndirectory named `values-en-rGB`, rename\nthe directory to `values-b+en+001` (International\nEnglish), because the most common\nparent for `en-GB` strings is `en-001`.\nThe following examples explain why these practices improve performance and\nreliability of resource resolution.\n\n### Resource resolution examples\n\nWith versions of Android greater than 7.0, the case described in\n**Table 1** is resolved differently:\n\n\n**Table 2.** An improved resolution strategy for when there is no\nexact locale match.\n\n| User Settings | App Resources | Resource Resolution |\n|---------------|--------------------------------------|---------------------------------------------------------------------------|\n| 1. fr_CH | default (en) de_DE es_ES fr_FR it_IT | Try fr_CH =\\\u003e Fail Try fr =\\\u003e Fail Try children of fr =\\\u003e fr_FR Use fr_FR |\n\nNow the user gets French resources instead of English. This example also shows\nwhy you should store French strings in `fr` rather than `fr_FR`\nfor Android 7.0 or higher. Here the course of action is\nto match the closest parent dialect,\nmaking resolution faster and more predictable.\n\nIn addition to this improved resolution logic, Android now offers more\nuser languages to choose from. Let's try the above example again with Italian\nspecified as an additional user language, but without app support for French.\n\n\n**Table 3.** Resource resolution when the app only matches the\nuser's second-preferred locale setting.\n\n| User Settings | App Resources | Resource Resolution |\n|-------------------|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|\n| 1. fr_CH 2. it_CH | default (en) de_DE es_ES it_IT | Try fr_CH =\\\u003e Fail Try fr =\\\u003e Fail Try children of fr =\\\u003e Fail Try it_CH =\\\u003e Fail Try it =\\\u003e Fail Try children of it =\\\u003e it_IT Use it_IT |\n\n\nThe user still gets a language they understand, even though the app doesn't\nsupport French.\n\nDesigning your app to support additional locales\n------------------------------------------------\n\nAndroid provides tools that make it easier to localize app content and engage users in their\npreferred languages. We recommend using the following techniques to configure your app so it can\naccommodate different languages and formatting conventions, in a scalable way.\n\n### Specify the languages your app supports\n\n\nTo ensure that languages are resolved correctly, specify the languages your app supports using the\n`resConfigs` property in the module-level `build.gradle` file.\n\nThe following code sample shows how to use `resConfigs` to denote languages supported.\nIn this example, the app supports both English and Spanish. \n\n### Groovy\n\n```groovy\nandroid {\n defaultConfig {\n ...\n resConfigs \"en\", \"es\"\n }\n}\n```\n\n### Kotlin\n\n```kotlin\nandroid {\n defaultConfig {\n ...\n resConfigs(\"en\", \"es\")\n }\n}\n```\nDue to the way the build system merges resources from your app and its dependencies, you must specify supported languages in this way to ensure that user language settings are received correctly.\n\n### LocaleList API\n\n\nStarting with Android 7.0 (API level 24), Android exposes the\n`LocaleList.getDefault()` API\nthat lets apps directly query the list of languages a user has specified. This API\nallows you to create more sophisticated\napp behavior and better-optimized display of content. For example, Search\ncan show results in multiple languages based on user's settings. Browser apps\ncan avoid offering to translate pages in a language the user already knows,\nand keyboard apps can auto-enable all appropriate layouts.\n\n### Formatters\n\n\nUp through Android 6.0 (API level 23), Android supported only one or\ntwo locales\nfor many common languages\n(en, es, ar, fr, ru). Because there were only a few variants of each language,\napps could get away with storing some numbers and dates as hard coded strings\nin resource files. However, with Android's broadened set of supported\nlocales, there can be\nsignificant differences in formats for dates, times, currencies, and similar\ninformation even within a single locale. Hard-coding your formats can produce\na confusing experience for end users.\nTherefore, when developing for Android 7.0 or higher versions,\nmake sure to use formatters instead of hard coding numbers and date strings.\n\n\nFor example, Android 7.0 and higher includes support for\n27 Arabic locales. These locales can share most resources,\nbut some prefer ASCII digits, while others prefer native digits. For example,\nwhen you want to create a sentence with a digit variable, such as\n\"Choose a 4 digit pin\", use formatters as shown below: \n\n```\n format(locale, \"Choose a %d-digit PIN\", 4)\n```"]]