昨天組里的同事遇到一些切換多語言的細(xì)節(jié)問題寒锚,發(fā)現(xiàn)在Android N版本上配置應(yīng)用內(nèi)多語言沒有生效,正好拿出來做為一個面試題講解一下。
面試題:如何實現(xiàn)應(yīng)用內(nèi)多語言切換呵哨?
我們知道Android的多語言實現(xiàn)很簡單叽讳,可以在不同的語言環(huán)境下使用不同的資源横殴。在不同的res/value-xx下放置不同語言的strings.xml實現(xiàn)字符的本地化,而這個value-xx目錄的選擇是根據(jù)Resource中的Configuration.Locale這項的值來決定的。如zh中文硅堆,就會選擇value-zh目錄,如果沒有匹配到(即APK中沒有value-zh目錄)就使用默認(rèn)的value目錄中的字符資源纯丸。
其實最終實現(xiàn)字符串的選擇都是在Assets這個類中剃氧,通過Native的方法來加載相應(yīng)的字符串資源。
然而谎柄,我們還是會有一些業(yè)務(wù)場景需要不根據(jù)Android系統(tǒng)的Locale配置就改變應(yīng)用的語言丁侄。實現(xiàn)的方式也很簡單,直接調(diào)用Android開放的接口Resources.updateConfiguration:
public static void changeSystemLanguage(Context context, String language) {
if (context == null || TextUtils.isEmpty(language)) {
return;
}
Resources resources = context.getResources();
Configuration config = resources.getConfiguration();
if (Locale.SIMPLIFIED_CHINESE.getLanguage().equals(language)) {
config.locale = Locale.SIMPLIFIED_CHINESE;
} else {
config.locale = new Locale(language);
}
resources.updateConfiguration(config, null);
}
上面的代碼朝巫,我們可以在應(yīng)用內(nèi)通過language的值指定是顯示哪種語言鸿摇,當(dāng)然language值我們需要保存在Preferences或者數(shù)據(jù)庫中。
好像很簡單劈猿,我們的項目為什么還會出現(xiàn)問題呢户辱?而且大家都不知道如何下手,因為在Android N之前的版本都是可以正常切換語言的糙臼。后來我跟了一下庐镐,發(fā)現(xiàn)在MainActivity和SplashActivity這些Activity有繼承了自已擴展的BaseActivity,而這個BaseActivity有這樣一段代碼:
@Override
public Resources getResources() {
Resources res = super.getResources();
Configuration config = new Configuration();
config.setToDefaults();
res.updateConfiguration(config, res.getDisplayMetrics());
return res;
}
config.setToDefaults會將Locale的值設(shè)為null变逃,而再調(diào)用updateConfiguration可能會根據(jù)Android系統(tǒng)的語言重新設(shè)置Resources中的Locale必逆。好吧,只是假設(shè)揽乱,還沒有看到Android N的源代碼名眉。不過去掉這段代碼后,在Android N(Preview)手機上切換語言正常了凰棉。
小結(jié)
今天遇到的問題损拢,是以前遺留的代碼埋下的坑終于暴露出來,也是這個項目缺乏代碼審查(Code Review)機制的結(jié)果撒犀。找了幾個人也無法說清覆寫getResources這個方法的用意福压,最終也只能按歷史問題處理了,是歷史總有一些說不清楚的事或舞,對吧荆姆。
回到這個面試題,現(xiàn)在你知道了可以在應(yīng)用內(nèi)切換語言(當(dāng)然也可以修改Configuration的其他值)映凳,那么你有沒有想過胆筒,如果不知道這個updateConfiguration的存在,你會怎么實現(xiàn)這個需求呢诈豌?或者說沒有人和你說過updateConfiguration仆救,你能找到它嗎抒和?