java - 管理动态本地化资源

标签 java android localization locale

为了这个问题,想象一下我的应用程序帮助用户练习外语。

他们按下一个按钮开始 Text to Speech 介绍,它说:

<string name="repeat_after_me" translatable="true">Repeat after me</string>

此字符串将以正常方式本地化,根据设备区域设置从适当的 res/values-lang/strings.xml 文件中获取字符串。

介绍后,应用程序需要说出随机数字符串中的任何一个,以他们当前希望学习的语言/区域设置。问题就出在这里。

假设 Text to Speech 从一个简单的方法开始,例如:

private void startLearning(Locale learningLocale)

伪代码为:

TTS.speak(getString(R.string.repeat_after_me)

其次是:

TTS.speak(getRandomLearningString(learningLocale))

地点:

String getRandomLearningString(Locale learningLocale) {
// return a random string here
}

上面是我一直坚持如何最好地引用 xml 资源的地方,它包含用户正在学习的语言的“字符串数组”(以便随机选择一个)。

<string-array name="en_EN" translatable="false">
    <item>"Where is the nearest hospital?"</item>
    <item>"What's the time please?"</item>
    <item>"Only if you promise to wear protection and we have a safe word"</item>
</string-array>

假设每种语言都有大量字符串并且我支持大量语言,问题:

我应该如何存储这些字符串以使其在开发过程中易于管理和读取?我应该如何从方法中“动态”引用它们?

澄清 - 主要问题不仅仅是我如何解决:

getStringArray(R.array.(variableLocale);

还有我如何/在哪里存储这些字符串数组,以便实现可扩展和有组织。

先谢谢你了。

编辑 - 切换语言的实际 Text to Speech 实现不是问题,我已经涵盖了。

最佳答案

可扩展解决方案

如果你想保持这种可伸缩性,你需要以一种支持随机访问的形式保存你的字符串,而不需要将所有内容都加载到内存中。因此,普通文件(本质上是 strings.xml)无法完成这项工作。

我建议您检查是否可以使用 SQLite 数据库 完成您想要的。

这会导致类似的结果:

SELECT text FROM table WHERE locale = yourlocale ORDER BY RANDOM() LIMIT 1

(参见 Select random row from an sqlite table)。


此解决方案需要大量工作来创建所需的数据库,因此对于已知的小情况,请使用以下解决方案。

有限的解决方案

如果您知道不会有太多条目,我建议您使用纯文本文件(每种语言一个)。它们最容易管理。

您可以将它们保存为原始资源 或保存在assets 文件夹中。两者都相对容易读入字符串。然后您只需调用 String.split("\n") 并获得一个数组,您可以从中随机选择一个数组。

或者,您可以将字符串放入每个本地化的strings.xml 中的字符串数组 中,并使用如下资源加载所需的数组:

Resources standardResources = context.getResources();
AssetManager assets = standardResources.getAssets();
DisplayMetrics metrics = standardResources.getDisplayMetrics();
Configuration config = new Configuration(standardResources.getConfiguration());
config.locale = yourLocale;
Resources resources = new Resources(assets, metrics, config);

(参见:Load language specific string from resource?)

正如源评论中所指出的,这似乎覆盖了从 context.getResources() 返回的资源,也许您之后必须重置为以前的语言环境。

从 Jellybean 开始还有 context.createConfigurationContext ,似乎没有这个问题。

在所有情况下,如果您需要重复选择条目,缓存数组可能是个好主意。


注意:此解决方案的扩展性不佳,因为必须将整个数组加载到内存中才能选择一个条目。因此,大型集合可能会超出您的堆或至少使用大量内存。

关于java - 管理动态本地化资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36212980/

相关文章:

Java 应用程序,线程在终止 MySQL 连接后挂起

android - 警告 : Different store and key passwords not supported for PKCS12 KeyStores. 忽略用户指定的 -keypass 值。在 Android Studio 中

c++ - 本地化字体

javascript - JS : How to format date and time string?

java - 在 Maven 构建的 JAR 中多次包含不同名称的文件

java - 如何给maven项目添加依赖? (如何从外部jar文件中查找GroupID/ArtifactID)

java - JComboBox 不显示结果

java - 制作副本后列表 <> 对象更改

android - 具有多个配置 Activity 的一个小部件 (Android)

android - AspectJ 为 onCreate() 方法添加切入点执行