App多语言实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了App多语言实现相关的知识,希望对你有一定的参考价值。

参考技术A

项目中遇到 切换app语言 的需求,要求在“简体中文”和“English”两种语言之间切换部分控件的语言文案,不受系统语言切换的影响。

TODO 切换系统Configuration设置源码分析

TODO android资源管理机制

按照Android的资源管理方式,我们需要在res目录下建立两个values目录,其中values是默认的路径,values-en是英文资源的目录。

默认情况下,app启动会根据系统的设置加载对应的资源,系统切换了语言设置,app也会更新设置,所以这样不能完全满足我们的需求。

我们不想要app随着系统语言的改变而改变,而是保持用户上一次的选择。默认安卓系统不会保留app的语言设置,我们需要本地记录一下用户的选择,在app重新启动的时候加载之前保存的语言资源。存储用户的选择比较容易,放到SharedPreference里即可。然后在app重新启动的时候,我们需要手动更新下app的Application、Activity、Fragment和Service收到的配置信息。

以Activity为例,我们在基类的attachBaseContext方法中更新保存有config信息的Context对象:

ConfigurationUtil.attachBaseContext(newBase) 方法中更新newBase对象,使其中保存的Locale为我们自定义,而非系统的。当Activity被attach到window时,调用到此方法,便会加载我们想要的资源。这时如果手动修改了系统语言设置,然后从任务历史中切回我们的app时,栈中的所有Activity会被系统依照展示次序依次销毁重建(栈顶被销毁重建,退出到前一个页面时,前一个页面会被销毁重建)。由于Activity被销毁重建,会重新执行了生命周期方法,Activity的attachBaseContext方法也就会被重新执行到,所以系统的语言修改后,我们仍然可以正确地加载到我们自己设置的语言资源,所以从表面上看并没有受到系统修改的影响。

通常官方也是建议我们重启所有Activity的,这么做会销毁旧的资源数据,重新加载新的,安全方便。

官方描述:

如果我们不希望在系统语言发生变化时重启Activity,需要在Manifest.xml文件中配置: android:configChanges="locale" 即可。

这样做之后我们会在重新回到Activity的时候,进入回调方法 public void onConfigurationChanged(Configuration newConfig) ... 中去执行。其参数newConfig对象代表所有当前配置,而不仅仅是已经变更的配置。

需要注意:当我们修改系统语言设置后,系统会更新当前手机中所有正在运行的进程里的所有组件(分析在开篇的链接里有说明),所以这种情况下再次回到Activity,如果我们刷新UI,UI会使用系统的设置加载相应的资源文件。比如,

假设我们app设置为了简体中文(我们在Application中保存相应的flag,来判断系统的语言设置是否和app的设置一致或者发生了变化),如果系统由简体中文修改为了English,如果我们不做上述处理,刷新UI会加载英文资源。

这并不是我们想要的效果,所以我们需要在onConfigurationChanged回调中,再次更新Context中的Resources设置。做法如下:

上述方案并非完美结局问题,onConfigurationChanged方法调用之前getResource()有可能就会被调用多次,时序问题,加载出依据系统的语言设置的资源文件。(。>︿<)_θ,所以会有4的兜底方案。

TODO 切换语言并回到app,然后新建fragment并add,会有资源加载错误情况
我们在Activity的onConfigurationChanged方法更新过资源,貌似这里没有起作用。有种暴力的方式:
我们在 getResources() 方法中调用 ConfigurationUtil.updateResources(getResources()); ,但是 getResources() 方法会被多次调用,每次调用会判断一次,并不是特别理想,不过可以及时刷新,再未找到更好的方法前也算是一种兜底的方案。

在切换的Activity中,我们最好重启一下所有的app,执行下方方法后,重新打开singleTask的MainActivity...

App Languages 批量导入管理Android(安卓)多语言文案

  自己最近开发了一款软件 App languages可以实现可视化的形式管理Android多语言文案,支持批量导入、批量删除、批量替换、批量导出以及导入前本地多语言文案,待导入多语言文案的异常检测。具体界面如下:

操作界面

批量导入

1)需要选择res文件夹的路径,方便创建和寻找本地的多语言文件
2)需要选择待导入excel文件的路径,其中待导入excel文件的格式如下:

备注:key是多语言的key对应的列名,后续的列名是每种语言的简写名称,default是默认的多语言文案

3)选择好以后点击按钮开始导入就开始执行了。执行过程中会进行如下操作

检测本地是否有多语言文件

  • 检测本地多语言文件中是否有重复的key,缺省的key

  • 检测excel文件中是否有重复的key,缺省的key

  • 检测excel文中的key在本地是否已经存在了

如果检测不通过会立即终止,会在按钮下方的运行日志中进行输出原因。

4)导入成功后会有toast进行提示,也可以通过运行日志看过结果,导入成功后截图如下

批量删除

有时候需要批量删除一些不再使用的多语言文案,操作界面如下:

具体步骤如下:
1)需要选择res文件夹的路径,方便寻找本地的多语言文件
2)需要选择待删除excel文件的路径,其中待删除excel文件的格式如下:

备注:setting就是要删除的key

3)点击开始删除就可以了,在这个过程中会进行如下的操作:

  • 检测本地是否有多语言文件

  • 检测本地多语言文件中是否有重复的key,缺省的key

  • 检测excel文件中是否有重复的key,缺省的key

  • 检测excel文中的key在本地是否不存在

如果检测不通过会立即终止,会在按钮下方的运行日志中进行输出原因。

4)执行完成后会有toast提示,也可以通过下方日志查看运行情况

批量替换

有时候需要批量替换一些不太准确的多语言文案,操作界面如下:

具体步骤如下:
1)需要选择res文件夹的路径,方便寻找本地的多语言文件
2)需要选择待替换excel文件的路径,其中待替换excel文件的格式如下:

备注:hintText就是要替换的key

3)点击开始删除就可以了,在这个过程中会进行如下的操作:

  • 检测本地是否有多语言文件

  • 检测本地多语言文件中是否有重复的key,缺省的key

  • 检测excel文件中是否有重复的key,缺省的key

  • 检测excel文中的key在本地是否存在

如果检测不通过会立即终止,会在按钮下方的运行日志中进行输出原因。

4)执行完成后会有toast提示,也可以通过下方日志查看运行情况

批量导出

有时候需要将项目中的多语言文案导出给其他人使用,操作界面如下:
  

具体使用步骤如下:

1)需要选择res文件夹的路径,方便寻找本地的多语言文件

2)需要选择需要待导出excel文件所在的文件夹

3)修改excel的名字,默认为AppLanguages

4)开始导出,执行过程中会执行如下操作:

  • 检测本地是否有多语言文件

  • 检测本地多语言文件中是否有重复的key,缺省的key

5)导出后会有toast提示,也可以通过运行日志查看,导出后的excel格式如下:

软件下载地址:https://apps.apple.com/cn/app/app-languages/id6444054918?mt=12

软件演示视频以及附件资料:https://pan.baidu.com/s/1fmc7ajkfi5LbaXWVGk75sQ?pwd=2zvd

以上是关于App多语言实现的主要内容,如果未能解决你的问题,请参考以下文章

App多语言实现

App Languages 批量导入管理flutter多语言文案

App Languages 批量导入管理flutter多语言文案

App Languages 批量导入管理Android多语言文案

App Languages 批量导入管理Android(安卓)多语言文案

App Languages 批量化导入管理iOS多语言文案