Android面试一天一题(12 Day)

作者: goeasyway | 来源:发表于2016-06-14 15:23 被阅读5217次

昨天组里的同事遇到一些切换多语言的细节问题,发现在Android N版本上配置应用内多语言没有生效,正好拿出来做为一个面试题讲解一下。

面试题:如何实现应用内多语言切换?

我们知道Android的多语言实现很简单,可以在不同的语言环境下使用不同的资源。在不同的res/value-xx下放置不同语言的strings.xml实现字符的本地化,而这个value-xx目录的选择是根据Resource中的Configuration.Locale这项的值来决定的。如zh中文,就会选择value-zh目录,如果没有匹配到(即APK中没有value-zh目录)就使用默认的value目录中的字符资源。

其实最终实现字符串的选择都是在Assets这个类中,通过Native的方法来加载相应的字符串资源。

然而,我们还是会有一些业务场景需要不根据Android系统的Locale配置就改变应用的语言。实现的方式也很简单,直接调用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);
    }

上面的代码,我们可以在应用内通过language的值指定是显示哪种语言,当然language值我们需要保存在Preferences或者数据库中。

好像很简单,我们的项目为什么还会出现问题呢?而且大家都不知道如何下手,因为在Android 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的值设为null,而再调用updateConfiguration可能会根据Android系统的语言重新设置Resources中的Locale。好吧,只是假设,还没有看到Android N的源代码。不过去掉这段代码后,在Android N(Preview)手机上切换语言正常了。

小结

今天遇到的问题,是以前遗留的代码埋下的坑终于暴露出来,也是这个项目缺乏代码审查(Code Review)机制的结果。找了几个人也无法说清覆写getResources这个方法的用意,最终也只能按历史问题处理了,是历史总有一些说不清楚的事,对吧。

回到这个面试题,现在你知道了可以在应用内切换语言(当然也可以修改Configuration的其他值),那么你有没有想过,如果不知道这个updateConfiguration的存在,你会怎么实现这个需求呢?或者说没有人和你说过updateConfiguration,你能找到它吗?

相关文章

  • Android面试一天一题-goeasyway

    以下文章作者:goeasyway Android面试一天一题(1 Day) Android面试一天一题(2 Day...

  • MS(1):Android之架构篇

    一、架构相关 1、MVC,MVP,MVVM MS思考:Android面试一天一题(Day 33:Android开发...

  • 面试题

    最全的BAT大厂面试题整理答案Android面试一天一题(Day 37:一套高级工程师的面试题)Android面试...

  • MS(2):Android之基础知识篇

    二、组件 1、Activity----------1 MS思考:Android面试一天一题(3 Day):Acti...

  • MS(7):非技术问题篇

    一、GM问非技术问题汇总 MS思考:Android面试一天一题(Day 34:常去的Android相关站点) 说下...

  • MS(3):Android之机制原理篇

    五、重点机制原理 1、Handler机制 MS思考:Android面试一天一题(8 Day):Handler相关分...

  • MS(5):android之进阶篇

    七、自定义View MS思考:Android面试一天一题(Day 30:老外的自定义View面试题)MS思考:老外...

  • android Service 一些思考

    看了Android面试一天一题(1 Day),对Service 的一些总结与思考 作者原文章链接: http://...

  • MS(6):Java篇

    MS思考:Android面试一天一题(7 Day):Java相关 1.Switch能否用string做参数? 在J...

  • 读goeasyway文章有感

    今天在地铁上读goeasyway的文章《Android面试一天一题(Day 39:写博客很重要吗?)》,很有感触,...

网友评论

  • Edgar_Ng:看了一下最新的源码,作者最后的猜想不是很对...
    以前的做法:
    config.setToDefaults会将Locale的值设为null,而再调用updateConfiguration会根据Android系统的之前的语言重新设置Resources中的Locale;
    if (o.locale != null) {
    locale = (Locale) o.locale.clone();
    }
    sdk-25的做法:
    config.setToDefaults会将Locale的值设为null,而再调用updateConfiguration会设置为null
    locale = o.locale == null ? null : (Locale) o.locale.clone();

    设置语言,25之前的可以config.setToDefaults();之后res.updateConfiguration(config, res.getDisplayMetrics());可以正常切换语言,但是25之后的不可以,
    因为config.setToDefaults();之后,config的local为null,这是一样的,变了的是,res.mTmpConfig.setTo(config); config.setTo()方法,local==null的时候是赋值为null,以前是==null的时候是不处理的,赋值为null之后,之后源码还会判断说,如果locales是空的话,就赋值一个默认的给它,因为手机默认是中文,想给APP设英文就会失败
  • 夏广成:那段代码可以阻止app的文字随手机字体的调整而调整。比如你把手机字体调整到最大,那么你app内的文字也会变到最大,然后app就面目全非
    流穿枫:@snowfly夏广成 :clap: :clap: 厉害了,我的哥。我刚才验证了一下。真是你说的这样
  • one_cup:之前的都能看懂也见过,这个是没见过
  • eric_qu:看了整篇后脑子里边第一个问题就是如果没看到这篇文章,我能从哪里获取到很多这种updateConfiguration 的知识。 这个确实是一个学习方法的问题。 楼主可否能在以后的文章中逐步介绍一下您获取知识的途径。
    13号大王:说说的发现途径: 远古时代下载了一个闹钟app,外国人开发,中文估计是机器翻译惨不忍睹,发现作者在settings中提供了切换语言的功能,这才知道,原来Android app可以在运行时更改语言。然后Google "change android app language runtime",搜索结果第一条就是。
    206945be346a:@ITIan 哈哈 就看你的关键字稳不稳
    ITIan:@eric_qu 谷歌,百度,我应该没说错
  • yzytmac:前两天做项目就遇到语言坑了,语言切换不及时,一半英文一半中文
    不吃肉的小屁孩: @雨小七 我觉得这个问题应该是你string文件的问题,你本身string文件就是一半中文一半英文吧
    goeasyway:@雨小七 是什么原因引起的?

本文标题:Android面试一天一题(12 Day)

本文链接:https://www.haomeiwen.com/subject/mfdudttx.html