第 15 章 应用本地化

请参考教材,全面理解和完成本章节内容... ...

复制工程ch13,将工程目录改名为ch14。

本地化是一个基于设备语言设置,为应用提供合适资源的过程。本章我们将对HelloMoon应用进行本地化,并为其提供中文版本的字符串资源。当设备的语言被设置为中文时,Android会自动找到并使用相应的中文资源,如图15-1所示。

图15-1 你好, 月球

15.1 本地化资源

语言设置是设备配置的一部分。Android提供了用于不同语言的配置修饰符。本地化处理因而变得简单:首先创建带有目标语言配置修饰符的资源子目录,然后将可选资源放入其中。Android资源系统会为我们处理其他后续工作。

语言配置修饰符来自于ISO 639-1标准代码。中文的修饰符为-zh。在HelloMoon项目中,打开res\raw目录,新建子目录:raw-zh; 打开res\values目录,新建子目录:values-zh。

在文件包中,找到文件:raw\one_small_step.wav 和values\strings.xml, 将文件分别复制到刚才新建的对应目录中。最后,将values-zh\strings.xml改成中文:

<string name="hellomoon_play">播放</string>
<string name="hellomoon_stop">停止</string>
<string name="hellomoon_description">尼尔·阿姆斯特朗踏上月球</string>

如此一来,便完成了为应用提供本地化资源的任务。如需验证成果,可打开Settings 应用,找到语言设置选项,然后将设备语言改为简体中文即可。尽管Android系统版本繁多,但语言设置选项通常被标为Language and input、Language and Keyboard或其他类似名称。

运行HelloMoony应用。单击播放按钮,欣赏阿姆斯特朗的著名讲话。

默认资源

中文语言的配置修饰符为-zh。本地化处理时,我们的第一反应可能是直接重命名原来的raw和values目录为raw-zh和values-zh。

这可不是个好主意。这些没有配置修饰符的资源是Android的默认资源。默认资源的提供非常重要。如果Android无法找到匹配设备配置的资源,而又没有默认资源可用时,应用将会崩溃。

例如,如果在values-en/以及values-zh/目录下分别有一个strings.xml文件,而在values/目录下并没有准备string.xml文件,那么运行在语言设置既非英文也非中文的设备上时,HelloMoon将会崩溃。因此,即便未提供匹配的设备配置资源,默认资源仍能保证应用的正常运行。

例外的屏幕显示密度

Android默认资源使用规则并不适用于屏幕显示密度。项目的drawable目录通常按屏幕显示密度要求,具有三类修饰符:-mdpi、-hdpi和-xhdpi。不过,Android决定使用哪一类drawable资源并不是简单地匹配设备的屏幕显示密度,也不是在没有匹配的资源时直接使用默认资源。

15.2 配置修饰符

目前为止,我们已经见识并使用过几个用于提供可选资源的配置修饰符,如语言(values-zh/)、屏幕方位(layout-land/)、屏幕显示密度(drawable-mdpi/)以及API级别(values-v11)。

表15-1列出了一些具有配置修饰符的设备配置特征,Android系统通过这些配置修饰符识别并定位资源。

表15-1 具有配置修饰符的设备特征


1


移动国家码,通常附有移动网络码


10


UI模式


2


语言代码,通常附有地区代码


11


夜间模式


3


布局方向


12


屏幕显示密度


4


最小宽度


13


触摸屏类型


5


可用宽度


14


键盘可用性


6


可用高度


15


首选输入法


7


屏幕尺寸


16


导航键可用性


8


屏幕纵横比


17


非文本导航方法


9


屏幕方位


18


API级别

15.2.1 可用资源优先级排定

考虑到有那么多定位资源的配置修饰符,有时可能会出现设备配置与好几个可选资源都匹配的情况。假设发生这种状况,Android会基于表15-1所示的顺序确定修饰符的使用优先级。

为实际了解这种优先级排定,我们来为HelloMoon应用再添加一种可选资源,即水平模式的app_name字符串资源。app_name资源将作为activity的标题显示在操作栏上。设备处于水平模式时,操作栏上可显示更多的文字。我们可以尝试设置一段对话,而不只是“你好,月球”这几个字。

创建一个values-land目录,然后将默认的字符串资源文件复制进去。

水平模式下,只需改变app_name字符串资源即可。删除其他无需变化的字符串资源,然后对照代码清单15-1修改app_name的值。

代码清单15-1 创建水平模式的字符串资源(values-land/strings.xml)

字符串备选资源(也包括其他values资源)都是基于每一个字符串提供,因此,字符串资源相同时,无需再复制一份。重复的字符串资源只会导致未来的维护噩梦。

现在有三个版本的app_name资源:values/strings.xml文件中的默认版本、values-zh/strings.xml文件中的中文备选版本以及values-land/strings.xml文件中的水平模式备选版本。

在设备语言设置为简体中文的前提下,运行HelloMoon应用,然后旋转设备至水平模式。因为中文备选版本资源优先级最高,所以我们看到的是来自于values-zh/strings.xml文件的字符串资源,如图15-2所示。

图15-2 Android排定语言优先级高于屏幕方位

也可以将设备的语言重新设置为英语语言,然后再次运行应用,确认水平模式下的备选字符串资源如期出现。

15.2.2 多重配置修饰符

可以在同一资源目录上使用多个配置修饰符。创建一个名为values-zh-land的资源目录,为HelloMoon应用准备水平模式的中文字符串资源。

在同一资源目录上使用多个配置修饰符,各配置修饰符必须按照优先级别顺序排列。因此,values-zh-land是一个有效的资源目录名,而values-land-zh目录名则无效。

注意,语言区域修饰符,如-es-rES,看上去像是由两个不同的配置修饰符组成的多重配置修饰符,但实际上它仅是一个独立的配置修饰符(区域部分本身不能构成一个有效的配置修饰符)。

将values-land/strings.xml文件复制到values-zh-land/目录中,然后按照代码清单15-2修改相应内容。

代码清单15-2 创建水平模式下的中文版字符串资源(values-zh-land/strings.xml)

在设备语言已设置为中文简体的前提下,运行HelloMoon应用,确认新的备选资源如期出现,如图15-3所示。

图15-3 水平模式下的中文字符串资源出现了

15.2.3 寻找最匹配的资源

我们来看看Android是如何确定app_name资源版本的。首先,记得当前设备有以下三个版本的app_name字符串备选资源:

  • values-zh/strings.xml

  • values-land/strings.xml
  • values-zh-land/strings.xml

其次,在设备配置方面,当前的设备配置包括中文简体语言以及水平屏幕方向。

排除不兼容的目录

要找到最匹配的资源,Android首先要做的就是将不兼容当前设备配置的资源目录排除掉。

结合备选资源和设备配置来看,三个版本的备选资源均兼容于设备的当前配置。如果将设备旋转至竖直模式,设备配置则会发生改变。此时,values-land/与values-zh-land/资源目录由于不兼容当前配置,因此可以被过滤掉。

有些配置修饰符的兼容性并不具有非黑即白的排他性。例如,API级别就不是一个严格匹配的修饰符。修饰符-v11可兼容运行API 11级及更高级别的系统版本设备。

有些配置修饰符被添加到较新的API级别中。例如,API 17级中引入的布局方向配置修饰符。该配置修饰符有两种选择:-ldltr(自左向右)和-ldrtl(自右向左)。比较晚添加的配置修饰符一般带有隐含的API级别修饰符,因此,-ldltr也可看作是-ldltr-v17。(这些附加的隐含配置修饰符也从另一方面解释了为何要以防万一在项目中准备默认资源。)

Android对屏幕显示密度采取了不同的处理方式。因此,通常的配置修饰符与设备配置兼容匹配的原则不适用于它。Android会选择其认为最合适的资源来匹配设备配置,这些资源可能是,也可能不是对应设备配置的配置修饰符目录下准备的资源。

按优先级表筛选不兼容目录

筛选掉不兼容的资源目录后,自优先级别最高的MCC开始,Android逐项查看并按优先级表继续筛选不兼容的目录(表15-1)。如有任何以MCC为配置修饰符的资源目录存在,那么所有不带有MMC修饰符的资源目录都会被排除掉。如果仍有多个目录匹配,则Android将继续按次高优先级进行筛选,如此反复,直至找到唯一满足兼容性的目录。

本例中没有目录包含MCC修饰符,因此无法筛选掉任何目录。接着,Android查看到次高优先级的设备语言修饰符。三个资源目录中,values-zh/和values-zh-land/目录包含语言修饰符,这样,不包含语言修饰符的values-land/即可被排除。

Android继续查看优先级表,接下来是屏幕方向。此时,Android会找到一个带屏幕方位的修饰符目录以及一个不带屏幕方向的目录,由此,values-zh/目录也被排除在外。就这样,values-zh-land/成了唯一满足兼容的目录。因而,Android最终确定使用values-zh-land/目录下的资源。

15.3 更多资源使用原则及控制

现在,我们已经对Android资源系统有了进一步的了解。不过,为将来开发自己的应用做准备,还应了解以下资源使用方面的要求。

15.3.1 资源命名

资源的名字只能由小写字母组成并且不能包含空格,一些正确命名的例子有:one_small_step.wav, app_name, armstrong_on_moon.jpg。

无论是在XML还是在代码中引用资源,引用都不应包括文件的扩展名。例如,在布局文件中引用的@drawable/armstrong_on_moon以及在代码中引用的R.drawable.armstrong_on_moon。这也意味着,在同一子目录下,不能以文件的扩展名为依据,来区分命名相同的资源文件。

15.3.2 资源目录结构

所有资源都必须保存在res/目录的子目录下。尝试在res/目录的根目录下保存资源将会导致编译错误。

res子目录的名字直接与Android编译过程绑定,因此无法随意进行更改。我们已看到过的子目录有drawable/、layout/、menu/、raw/以及values/等。

Android会无视res/目录下的其他子目录。创建res/my_stuff可能不会导致错误发生,但Android不会使用放置在其中的任何资源。

此外,我们也无法在res/目录下创建多级子目录。这种限制会给开发带来些许麻烦。要知道,实际开发项目中往往有几百个drawable资源。因此,创建多级子目录来管理这些资源文件是很自然的想法,但Android不允许这样做。既然这样,我们唯一能做的就是有意识的对资源命名,使其可按文件名进行排序,以便于查找某个特定文件。

Android对布局文件的命名约定就是按文件名排序的典型例子。布局文件通常以其定义的视图类型名作为前缀,如activity_dialog_,以及list_item_等。例如,在CriminalIntent应用的res/layout/目录下,一些布局命名有:activity_crime_pageractivity_fragmentdialog_datefragment_crimelist_item_crime。可以看到,activity布局按照名称进行排序,这样查找某个activity布局文件就容易多了。

15.4 测试备选资源

应用开发时,布局以及其他资源的测试非常重要。针对不同尺寸的屏幕、屏幕方位等设备配置,布局测试可提前让我们知道所需的备选资源数量。我们可以在虚拟设备上测试,也可以在实体设备上测试,甚至还可以使用图形布局工具进行测试。

图形布局工具提供了很多选项,用以预览布局在不同配置下的显示效果。这些选项有屏幕尺寸、设备类型、API级别以及设备语言等。

要查看这些选项,可在图形布局工具中打开fragment_hello_moon.xml文件。然后参照图15-4,尝试使用各种选项对布局进行预览。

图15-4 使用图像布局工具预览资源

通过设置设备语言为未提供本地化资源的语言,可确保项目已包括所有必需的默认资源。运行应用进行测试,查看所有视图界面并旋转设备。如应用发生崩溃,请查看LogCat中“Resource not found...”错误信息,确认缺少哪些默认资源。

时间: 2024-12-16 10:32:24

第 15 章 应用本地化的相关文章

java第15章示例代码

import java.util.Scanner; /** * * @author asus第15章示例代码1 全桂群2017.4.9 * */public class Registter { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); String uname, pw

第15章 就不能换DB吗?—抽象工厂模式

由于抽象工厂在我们编程当中经常使用和常见,所有本篇文章对<大话设计模式>中的15章做了很详细的比较.通过一个Dao层可以更换访问任意数据库的例子来学习抽象工厂模式.例如:Dao层可以访问Sqlserver数据库,也可以访问Access数据库,当程序新增访问Oracle数据库时,无需修改现有代码,只需要添加访问Oracle相关的类就可以,实现了开闭原则.本篇文章的例子中每种数据库上都有User和Department表,我们Dao层对这两个表进行查询和插入操作. 最基本数据库访问 一下是访问Sql

《白帽子讲WEB安全》学习笔记之第15章 web server配置安全

第15章 web server配置安全 15.1 apache安全 在linux部署安装web Server时候一定主要要使用"最小权限原则".尽量不要使用root部署. 15.2 nginx安全 Nginx 安全配置指南技术手册 PDF 下载 免费下载地址在http://linux.linuxidc.com/ 用户名与密码都是www.linuxidc.com 具体下载目录在 /pub/服务器相关教程/Nginx/Nginx 安全配置指南技术手册/ 参考资料:http://my.osc

【Android】15.0 第15章 广播和通知&mdash;本章示例主界面

分类:C#.Android.VS2015: 创建日期:2016-02-28 一.简介 广播(Broadcast):其功能类似于收音机的广播,你只要调到那个台(只要在接收的类中注册了要接收的广播),就能收到这个台播放的信息. 通知(Notifications):安卓的服务组件(Android Service,后面章节再细讲)本来是在后台运行的,可是,用户可能希望关注某个后台任务当前正在执行的状态或者结果,此时就可以利用"通知"在前台告诉用户. 二.本章示例主界面 1.运行截图 这个截图也

敏捷软件开发:原则、模式与实践——第15章 状态图

第15章 状态图 在描述有限状态机(FSM)方面,UML提供个丰富的符合. 15.1 基础知识 下图是一个简单的状态迁移图(STD),该图描述了控制用户登录到系统的FSM.圆角矩形表状态.上层格间放置每个状态的名字.下层格间中放置的是一些特定动作,表示当进入或退出该状态时要做什么. 图中左上角的实心圆称为初始伪状态.FSM从这个伪状态开始,根据变迁规则进行转移. 15.1.1 特定事件 状态图的下层格间含有事件/动作对. 15.1.2 超状态 当许多状态以同样的方式响应某些同样的事件时,使用超状

第15章 hash_set哈希集合容器

/* 第15章 hash_set哈希集合容器   15.1 hash_set技术原理   15.2 hash_set应用基础   15.3 本章小结 略 */

第 15 章 组合模式【Composite Pattern】

以下内容出自:<<24种设计模式介绍与6大设计原则>> 大家在上学的时候应该都学过“数据结构”这门课程吧,还记得其中有一节叫“二叉树”吧,我们上 学那会儿这一章节是必考内容,左子树,右子树,什么先序遍历后序遍历什么,重点就是二叉树的的遍历,我还记得当时老师就说,考试的时候一定有二叉树的构建和遍历,现在想起来还是觉的老师是正确的,树状结果在实际项目应用的非常广泛. 咱就先说个最常见的例子,公司的人事管理就是一个典型的树状结构,你想想你公司的结构是不是这样: 老大,往下一层一层的管理,

第三部分 基本类型:第15章 枚举类型和位标志

15.1 枚举类型枚举类型定义了一组“符号名称/值”配对.例如,以下Color类型定义了一组符合,每个符号表示一种颜色. internal enum Color{ White, //赋值0 Red, //赋值1 Green, //赋值2 Blue, //赋值3 Orange //赋值4 } 枚举类型的好处:枚举类型容易编写.阅读和维护.枚举类型是强类型. 派生关系:System.Object -> System.ValueType -> System.Enum -> 枚举类型 枚举类型是

C++ Primer Plus 第15章 友元、异常和其他

第15章 友元.异常和其他 1.友元不仅有友元函数,还能是友元类 还可以将类中的某一个成员函数指定为另一个类的友元 尽管友元被授予从外部访问私有部门的权限,单并不与面向对象编程思想相愽,相反,它们提高了公有接口的灵活性 2.类的成员函数作为其他类的友元,涉及到类的声明顺序. 还有一个函数作为两个类的友元 这方面内容看P607-611 3.嵌套类:在另一个类中声明的类被称为嵌套类 类嵌套与包含不一样.包含意味着将一个类对象作为另一个类的成员,而对类进行嵌套不创建类成员,而是定义了一种类型. 4.对