blob: 248d6a06c7bfcc5acd8167c8a926c7a51b550882 [file] [log] [blame]
page.title=语言和区域设置
page.tags=androidn
page.image=images/cards/card-nyc_2x.jpg
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>本文内容:</h2>
<ol>
<li><a href="#preN">解析语言资源所面临的挑战</a></li>
<li><a href="#postN">对资源解析策略的改进</a></li>
<li><a href="#design">设计您的应用以支持附加区域设置</a>
</li>
</ol>
</div>
</div>
<p>Android N 为多语言用户提供增强的支持,让他们可以在设置中选择多个区域设置。
Android N 通过大幅扩展受支持的区域设置数量并更改系统解析资源的方式来提供此功能。
全新的解析资源方法更加稳健,并且设计为与现有 APK 兼容,但要格外细心,以发现任何异常行为。
例如,您应进行测试,以确保应用默认显示预期的语言。
另外,如果应用支持多语言,您应确保此支持合乎预期。
最后,对于您没有将其显式设计为支持的语言,应设法确保应用能够妥善地处理它们。
</p>
<p>本文档开头介绍 Android N 之前的资源解析策略。接下来介绍 Android N 改进的资源解析策略。
最后,介绍如何充分利用扩展的区域设置数量来支持更多的多语言用户。
</p>
<h2 id="preN">解析语言资源所面临的挑战</h2>
<p> Android N 之前,Android 并非始终能够成功匹配应用和系统区域设置。
</p>
<p>例如,假设您遇到了以下情况:</p>
<ul>
<li>您的应用的默认语言为{@code en_US}“US English”,但它也在 {@code es_ES}资源文件中对西班牙字符串进行了本地化。
</li>
<li> 将设备设置为 {@code es_MX} </li>
<p>当您的 Java 代码引用字符串时,系统会从默认 ({@code en_US}) 资源文件加载字符串,即使应用在 {@code es_ES} 下有本地化的西班牙语资源。
这是因为当系统无法找到精确匹配时,它会继续通过将国家/地区代码从区域设置中剥离来查找资源。
最后,如果未找到匹配,系统会恢复为默认模式,即 {@code en_US}。
</p>
<p>如果用户选择应用根本不支持的语言(如法语),则系统也会默认显示 {@code en_US}。
例如:</p>
<p class="table-caption" id="t-resource-res">
<strong> 1.</strong> 没有精确区域设置匹配项的资源解析。
</p>
<table>
<tbody>
<tr>
<th>用户设置</th>
<th>应用资源</th>
<th>资源解析</th>
</tr>
<tr>
<td>fr_CH</td>
<td>
默认值 (en)<br>
de_DE<br>
es_ES<br>
fr_FR<br>
it_IT<br>
</td>
<td>
尝试 fr_CH =&gt; 失败<br>
尝试 fr =&gt; 失败<br>
使用默认值 (en)
</td>
</tr>
</tbody>
</table>
<p>在此示例中,系统在不知道用户是否理解英语的情况下显示英语字符串。
目前,此行为很常见。
Android N 应该会大幅减少出现此类结果的频率。
</p>
<h2 id="postN">对资源解析策略的改进</h2>
<p>Android N 可提供更稳健的资源解析,并自动查找更好的备用方法。
不过,为了加速解析和提升可维护性,您应以最常用的母语存储资源。
例如,如果您之前将西班牙语资源存储在 {@code es-US} 目录中,请将它们移动到 {@code es-419} 目录,该目录包含拉丁美洲西班牙语。
同理,如果您在名为 {@code en-GB} 的文件夹中存储有资源字符串,则将此文件夹重命名为 {@code en-001}(国际英语),因为 <code>en-GB</code> 字符串的最常用母语为 {@code en-001}。
以下示例介绍为什么这些做法可提升性能和资源解析的可靠性。
</p>
<h3>资源解析示例</h3>
<p>使用 Android N,以不同的方式解析<strong>表 1</strong> 中所描述的案例:
</p>
<p class="table-caption" id="t-improved-res">
<strong> 2.</strong> 针对没有精确区域设置匹配项时改进的资源解析策略。
</p>
<table>
<tr>
<th>用户设置</th>
<th>应用资源</th>
<th>资源解析</th>
</tr>
<tr>
<td><ol>
<li> fr_CH</li>
</ol>
</td>
<td>
默认值 (en)<br>
de_DE<br>
es_ES<br>
fr_FR<br>
it_IT<br>
</td>
<td>
尝试 fr_CH =&gt; 失败<br>
尝试 fr =&gt; 失败<br>
尝试 fr 的子项 =&gt; fr_FR<br>
使用 fr_FR
</td>
</tr>
</table>
<p>现在,用户获得的是法语资源而不是英语。此示例还表明对于 Android N,您为什么应将法语字符串存储在 {@code fr}(而非 {@code fr_FR})中。此处的做法是匹配最接近的母语,从而使解析更快速且更具预见性。
</p>
<p>除了这个改进的解析逻辑外,Android 现在还提供更多的用户语言以供选择。
下面,我们将意大利语指定为附加用户语言,但假设应用不支持法语,再次尝试上面的示例。
</p>
<p class="table-caption" id="t-2d-choice">
<strong> 3.</strong> 应用仅与用户的次优区域设置匹配时的资源解析。
</p>
<table>
<tr>
<th>用户设置</th>
<th>应用资源</th>
<th>资源解析</th>
</tr>
<tr>
<td><ol>
<li> fr_CH</li>
<li> it_CH</li>
</ol>
</td>
<td>
默认值 (en)<br>
de_DE<br>
es_ES<br>
it_IT<br>
</td>
<td>
尝试 fr_CH =&gt; 失败<br>
尝试 fr =&gt; 失败<br>
尝试 fr 的子项 =&gt; 失败<br>
尝试 it_CH =&gt; 失败<br>
尝试 it =&gt; 失败<br>
尝试 it 的子项 =&gt; it_IT<br>
使用 it_IT
</td>
</tr>
</table>
<p>用户仍会获取他们理解的语言,即使应用不支持法语。
</p>
<h2 id="design">设计您的应用以支持附加区域设置</h2>
<h3>LocaleList API</h3>
<p>Android N 添加了新的 API {@code LocaleList.getDefault()},从而让应用可以直接查询用户已指定的语言列表。
您可以使用此 API 创建更成熟的应用行为和更优化的内容显示。
例如,搜索可以基于用户的设置以多种语言显示结果。
浏览器应用可避免翻译以用户理解的语言显示的页面,键盘应用可自动启用所有适用的布局。
</p>
<h3>格式化程序</h3>
<p>直到 Android 6.0API 级别 23),Android 仅支持许多常用语言(enesarfrru)的一个或两个区域设置。
由于每种语言只有几种变体,因此,应用可以通过在资源文件中将一些数字和日期存储为硬编码字符串解决此问题。
不过,随着 Android 扩展了支持的区域设置集,即使在一个区域设置中,日期、时间、货币及类似信息也会存在显著差异。
对您的格式进行硬编码会让最终用户困惑不已。
因此,在针对 Android N 开发应用时请务必使用格式化程序代替硬编码数字和日期字符串。
</p>
<p>阿拉伯语就是最好的例子,Android N 将对其的支持从一个 {@code ar_EG} 扩展到 27 个阿拉伯语区域设置。
这些区域设置可以共享大多数资源,但其中一些资源首选 ASCII 数字,另一些则首选本地数字。
例如,如果您想要创建一个具有数字变量的句子,如“Choose a 4 digit pin”,则按如下所示使用格式化程序:
</p>
<pre> format(locale, "Choose a %d-digit PIN", 4)</pre>