之前负责的APP中做了应用内语言切换。但是后来测试提出bug,在Android7(N)的手机中会发生语言混乱的现象。经查看,发现只要是打开了含有WebView的页面,应用内语言切换就会失效。一口老血喷出来。
好吧,既然问题出现了。那就开始着手搜索解决。
之后在万能的StackOverFlow上找到了如下问题及回答:
Android - WebView language changes abruptly on Android N
好吧简单总结一下这个问题的产生原因及解决方案。
1、问题原因:
在Android7(N)之前WebView的渲染是通过Android System webView来实现的。但是在Android7(N)之后WebView会被作为一个应用程序的方式服务于各个三方APP。由于WebView这里是作为一个单独的应用程序,所以他不会被绑定到你自己APP设置的Local上。不仅如此,WebView还会把语言变成设备的Local设置。然后相应的资源文件也会被变成设备语言下的资源文件。这样就导致了只要打开了含有WebView的页面,应用内语言设置就失效的问题。
2、解决方案:
(1)第1步,在所有Activity下重设语言。StackOverFlow的回答中说也可以只在含有WebView的Activity中重设。但是各位,为了保证不给自己挖坑,还是全设置掉好一点。在你的BaseActivity中,并且在调用setContentView之前调用如下代码设置你的Local:
public static void setLocale(Locale locale){
Locale.setDefault(locale);
Context context = MusafirApplication.getInstance();
final Resources resources = context.getResources();
final Configuration config = resources.getConfiguration();
config.setLocale(locale);
context.getResources().updateConfiguration(config,
resources.getDisplayMetrics());
}
(2)第2步:在你的Application的onCreate方法中添加如下代码:
new WebView(this).destroy();
这样之后,问题解决。
3、我自己的实践:
这里贴上我的部分代码,仅供参考。
系统工具类部分代码:
public class SystemUtil {
public static final String EN = "en";
public static final String CN = "cn";
//切换应用内语言
public static void switchLanguage(String language) {
Resources resources = BaseApplication.getInstance().getResources();
Configuration config = resources.getConfiguration();
DisplayMetrics dm = resources.getDisplayMetrics();
if (TextUtils.equals(EN, language)) {
config.setLocale(Locale.ENGLISH);
} else {
config.setLocale(Locale.SIMPLIFIED_CHINESE);
}
resources.updateConfiguration(config, dm);
}
//判断当前应用内语言是否为中文
public static boolean getLocalLanguageIsCN() {
Resources resources = BaseApplication.getInstance().getResources();
Configuration config = resources.getConfiguration();
Locale locale = config.locale;
if (locale.equals(Locale.ENGLISH)) {
return false;
} else {
return true;
}
}
}
BaseActivity类部分代码:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getApplicationContext();
if (SystemUtil.getOSVersionSdkInt() >= Build.VERSION_CODES.N) {
if (SystemUtil.getSystemLanguageIsCN()) {
SystemUtil.switchLanguage(SystemUtil.CN);
} else {
SystemUtil.switchLanguage(SystemUtil.EN);
}
}
}
}
Application部分代码:
public class BaseApplication extends MultiDexApplication {
private static BaseApplication sInstance = null;
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
initWebView();
}
//处理Android7(N)webview导致应用内语言失效的问题
private void initWebView(){
new WebView(this).destroy();
}
public static synchronized BaseApplication getInstance() {
return sInstance;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (TextUtils.equals(SharedPreferencesUtil.getSPLocalLanguage(this), SystemUtil.CN)) {
SystemUtil.switchLanguage(SystemUtil.CN);
} else {
SystemUtil.switchLanguage(SystemUtil.EN);
}
}
}