问题: 在切换系统语言的时候,发现有些语言显示为默认语言, 比如系统语言为法语, 应用程序中对应的文字却使用默认的语言。
调查:
1. 资源文件中 res/values-fr res/valuse-it 等等资源文件都在 没有缺失
2. 看Android.mk, LOCAL_AAPT_FLAGS := -c zz_ZZ
3. 使用 aapt d resources XXX.apk 查看apk中的resouces, 发现只有 default en es de zh zz_ZZ等config, 没有fr it pt ca等等
分析:
在apk编译生成过程中,部分资源文件没有打包到apk。
验证:
指定打包资源文件,如下
LOCAL_AAPT_FLAGS := -c fr,it,pt,zz_ZZ
编译生成新的APK,aapt d resources 查看 发现有fr it pt等资源,install, 语言也可以正常切换了。
为什么默认情况下没有打包fr it pt等资源文件呢?
查看aapt说明, -c选项缺省情况下打包默认配置, 难道fr it pt等不属于默认配置吗?
上网查了一些资料,设备的一些默认配置由build/core/product_config.mk配置, 而这个文件显示aapt默认config由PRODUCT_LOCALES配置
发现PRODUCT_LOCALES在build/target/product/locale_full.mk中设置了所有语言,
而在对应设备目录下(device/xxx/xxx/device.mk)有如下一行
PRODUCT_LOCALES := en es de zh
怀疑 PRODUCT_LOCALES被重置了,导致默认config只包括部分语言。
删掉这一行重试, 问题就解决了。
在makefile中将PRODUCT_LOCALES的值打印输出观察发现
product是由设备特有makefile和通用的makefile配置的,
build系统通过设备目录下的AndroidProducts.mk 获得该设备的配置makefile,
而所有的配置makefile之间通过inherit-product函数构成继承关系。
具体语句为 $(call inherit-product, path/to/config.mk)
表明当前makefile继承path/to/config.mk中的变量定义, 这些变量是以PRODUCT_开头的变量。
但是这个继承不是立刻的, 比如
在执行inherit-product之前, PRODUCT_LOCALES为空,
那执行之后, PRODUCT_LOCALES就变成了 @inherit:path/to/config.mk ,而不是具体的语言config,
解析的工作应该是在之后某个时刻做的, 具体就没有调查。
root cause:
设备配置makefile中是这样写的
$(call inherit-product, path/to/config.mk) #这一继承里包括了所有的语言
.....
PRODUCT_LOCALES := en es de zh #这一步导致@inherit:path/to/config.mk丢失,从而不能继承config.mk中的定义,导致默认只包含部分语言。