我有一个多语言的应用程序与主要语言英语和第二语言阿拉伯语.
如documentation所述,
>我在清单中添加了android:supportsRtl =“true”.
>我已经将左右属性的所有xml属性分别更改为start和end.
>我在strings-ar中添加了阿拉伯语言字符串(对于其他资源也是如此).
以上设置正常.将区域设置更改为ar-AE后,阿拉伯语文本&资源在我的活动中正确显示.
However, every time I navigate to an
Activity
with aWebView
and/or aWebViewClient
, the locale, text and layout direction
abruptly revert to the device default.
进一步提示:
>这仅在具有Android 7.0的Nexus 6P上发生.一切都在Android 6.0.1及更低版本上正常运行.
>当我导航到具有WebView和/或WebViewClient的Activity(我有几个)时,才会发生语言环境的突然转变.它不会发生在任何其他活动上.
Android 7.0具有多语言环境支持,允许用户设置多个默认语言环境.因此,如果我将主要语言环境设置为Locale.UK:
Then on navigating to the
WebView
, the locale changes fromar-AE
toen-GB
.
Android 7.0 API更改:
如list of API changes所示,API 24中的以下类中添加了与语言环境相关的新方法:
地点:
> Locale.getDefault(...)
> Locale.setDefault(...)
组态:
> getLocales()
> setLocales(...)
However, I am building my app with API 23, and am not using any of
these new methods.
此外……
>问题也出现在Nexus 6P仿真器上.
>要获取默认语言环境,我使用的是Locale.getDefault()
.
>要设置默认语言环境,我使用以下代码:
public static void setLocale(Locale locale){
Locale.setDefault(locale);
Configuration config = new Configuration();
config.setLocale(locale);
Context context = MyApplication.getInstance();
context.getResources().updateConfiguration(config,
context.getResources().getDisplayMetrics());
}
以前有人遇到过这个问题吗?它是什么原因,我该如何解决这个问题?
参考文献:
1. Native RTL support in Android 4.2
2. Multilingual Support – Language and Locale.
3. Be wary of the default locale.
解决方法:
Ted Hopp’s answer设法解决了这个问题,但他没有解决为什么会这样的问题.
原因是对Android 7.0中的WebView
类及其支持包进行了更改.
背景:
Android的WebView是使用WebKit构建的.虽然它最初是AOSP的一部分,但是从KitKat开始,我们决定将WebView分拆成一个名为Android System WebView的独立组件.它本质上是一个预先安装了Android设备的Android系统应用程序.它会定期更新,就像其他系统应用程序一样,例如Google Play服务和Play商店应用.您可以在已安装的系统应用列表中看到它:
Android 7.0更改:
从Android N开始,Chrome应用将用于在第三方Android应用中呈现任何/所有WebView.在具有Android N开箱即用功能的手机中,Android WebView System应用程序根本不存在.在已收到Android N的OTA更新的设备中,Android系统WebView被禁用:
和
此外,还引入了多语言环境支持,设备具有多种默认语言:
这对于具有多种语言的应用程序具有重要意义.如果您的应用具有WebView,则会使用Chrome应用进行渲染.由于Chrome本身就是一个Android应用,在自己的沙盒流程中运行,因此它不会绑定到您的应用设置的区域设置.相反,Chrome将恢复为主要设备区域设置.例如,假设您的应用区域设置设置为ar-AE,而设备的主要区域设置为en-US.在这种情况下,包含WebView的Activity的语言环境将从ar-AE更改为en-US,并且将显示来自相应语言环境文件夹的字符串和资源.您可能会在具有WebView的Activity上看到混合LTR和RTL字符串/资源.
解决方案:
该问题的完整解决方案包括两个步骤:
步骤1:
首先,在每个Activity中手动重置默认语言环境,或者至少在具有WebView的每个Activity中重置默认语言环境.
public static void setLocale(Locale locale){
Context context = MyApplication.getInstance();
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
Locale.setDefault(locale);
configuration.setLocale(locale);
if (Build.VERSION.SDK_INT >= 25) {
context = context.getApplicationContext().createConfigurationContext(configuration);
context = context.createConfigurationContext(configuration);
}
context.getResources().updateConfiguration(configuration,
resources.getDisplayMetrics());
}
在调用所有活动的onCreate()方法中的setContentView(…)之前调用上面的方法. locale参数应该是您要设置的默认语言环境.例如,如果您希望将阿拉伯语/ UAE设置为默认语言环境,则应传递新的语言环境(“ar”,“AE”).或者,如果要设置默认语言环境(即操作系统自动设置的语言环境),则应传递Locale.US.
第2步:
此外,您还需要添加以下代码行:
new WebView(this).destroy();
在Application类的onCreate()中(如果有的话),以及用户可能在何处更改语言.这将处理在更改语言后应用程序重新启动时可能出现的各种边缘情况(在更改Android 7.0上具有WebViews的活动上的语言后,您可能已经注意到其他语言中的字符串或具有相反的对齐方式).
作为附录,Chrome custom tabs现在是呈现应用内网页的首选方式.
参考文献:
1. Android 7.0 – changes for WebView
2. Understanding WebView and Android security patches.
4. WebView: From “Powered by Chrome” to straight up Chrome.
5. Nougat WebView.
7. Android N Mysteries, Part 1: Android System WebView is just “Chrome” Now?.