Android 应用 内部切换语言的需求其实挺多的,比如支付宝,微信等。

实现代码

其实这个代码网上一搜就出来了

public class LanguageUtils{
    public void setLanguage(Context context, String lan){
        Resources res = context.getResources();
        Locale current = new Locale(lan);
        Configuration conf = res.getConfiguration();
        conf.locale = current;
        res.updateConfiguration(conf, res.getDisplayMetrics());
    }
}

当用户在界面上更改语言后会调用此方法进行变更语言。当然你可以保存起来,以便下次启动时恢复。

问题

  1. 应用在使用过程中可能恢复“设置”中本地语言的界面
    出现此问题的原因参考Android源码分析-资源加载机制此博文,引用如下片段

根据上述代码中资源的请求机制,再加上ResourcesManager采用单例模式,这样就保证了不同的ContextImpl访问的是同一套资源,注意,这里说的同一套资源未必是同一个资源,因为资源可能位于不同的目录,但它一定是我们的应用的资源,或许这样来描述更准确,在设备参数和显示参数不变的情况下,不同的ContextImpl访问到的是同一份资源。设备参数不变是指手机的屏幕和android版本不变,显示参数不变是指手机的分辨率和横竖屏状态。也就是说,尽管Application、Activity、Service都有自己的ContextImpl,并且每个ContextImpl都有自己的mResources成员,但是由于它们的mResources成员都来自于唯一的ResourcesManager实例,所以它们看似不同的mResources其实都指向的是同一块内存(C语言的概念),因此,它们的mResources都是同一个对象(在设备参数和显示参数不变的情况下)。在横竖屏切换的情况下且应用中为横竖屏状态提供了不同的资源,处在横屏状态下的ContextImpl和处在竖屏状态下的ContextImpl访问的资源不是同一个资源对象。

说明参数不变的情况使用同一份资源,出现上面的问题是参数发生变化了,也就是在setLanguage中设置的Locale又恢复到默认状态了。
解决此问题即在Activity.onCreate()、onConfigurationChanged(Configuration newConfig)中再次调用setLanguage()方法进行设置,保证参数变更时,Resources.configuration处于同步状态的Locale.  
2.  关于调用setLanguage()方法后界面并未发生变化    
 调用此方法并不会触发onCreate()方法或者界面刷新,所以需要自己维护Activity栈。
 解决:变更语言后,打开MainActivity(主界面),然后结束非栈顶的所有Activity。