Android-WebView语言在Android 7.0及更高版本上突然改变 [英] Android - WebView language changes abruptly on Android 7.0 and above
问题描述
我有一个使用多种语言的应用程序,其中包含主要语言的英语和次要语言的阿拉伯语.
I have a multilingual app with primary language English and secondary language Arabic.
如文档中所述,
- 我已在清单中添加了
android:supportsRtl="true"
. - 我已将所有具有
left
和right
属性的xml属性分别更改为start
和end
. - 我已经在
strings-ar
中添加了阿拉伯语言字符串(对于其他资源也是如此).
- I have added
android:supportsRtl="true"
in the manifest. - I have changed all xml properties with
left
andright
attributes tostart
andend
respectively. - I have added Arabic language strings in
strings-ar
(and similarly for other resources).
以上设置正常运行.将Locale
更改为ar-AE
后,阿拉伯文字&资源正确显示在我的活动中.
The above setup works properly. After changing the Locale
to ar-AE
, Arabic text & resources are correctly displayed in my Activities.
但是,每次我使用
WebView
导航到Activity
和/或WebViewClient
,语言环境,文本和布局方向 突然恢复为设备默认值.
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
时,语言环境的突然变化只发生 (并且我有几个).在其他任何活动中都不会发生.
- This is occurring only on a Nexus 6P with Android 7.0. Everything works properly on Android 6.0.1 and below.
- The abrupt shift in locale happens only when I navigate to an
Activity
that has aWebView
and/or aWebViewClient
(and I have several). It does not occur on any of the other Activities.
Android 7.0具有多语言环境支持,允许用户设置多个默认语言环境.因此,如果我将主要语言环境设置为Locale.UK
:
Android 7.0 has multi-locale support, allowing the user to set more than one default locale. So if I set the primary locale to Locale.UK
:
然后在导航到
WebView
时,区域设置从ar-AE
更改 到en-GB
.
Then on navigating to the
WebView
, the locale changes fromar-AE
toen-GB
.
Android 7.0 API更改:
如 API更改列表中所述,与之相关的新方法语言环境中的语言已添加到API 24中的以下类中:
As indicated in the list of API changes, new methods pertaining to locale have been added to the following classes in API 24:
Locale
:
Locale
:
-
Locale.getDefault(...)
-
Configuration
:Configuration
:但是,我正在使用API 23构建我的应用,并且未使用任何 这些新方法.
However, I am building my app with API 23, and am not using any of these new methods.
此外...
-
此问题在Nexus 6P模拟器上也会发生.
The problem occurs on the Nexus 6P emulator as well.
To get the default locale, I am using
Locale.getDefault()
.要设置默认语言环境,我使用以下代码:
To set the default locale, I am using the following code:
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()); }
-
以前有人遇到过此问题吗?原因是什么?我该如何解决?
Has anyone encountered this problem before? What is the reason for it, and how do I resolve this?
参考:
1.. 2.. 多语言支持-语言和语言环境 .
3.. 请注意默认语言环境 .
推荐答案
Ted Hopp的答案设法解决了这个问题,但是他没有解决 为什么 发生这种情况的问题.
Ted Hopp's answer managed to solve the problem, but he didn't address the question of why this occurs.
原因是对 WebView
类进行了更改及其在Android 7.0中的支持包.
The reason is the changes made to the WebView
class and its support package in Android 7.0.
背景:
Android的WebView
是使用 WebKit 构建的.虽然它最初是AOSP的一部分,但从KitKat开始,决定将WebView
拆分为一个名为
Android's WebView
is built using WebKit. While it was originally a part of AOSP, from KitKat onwards a decision was made to spin off WebView
into a separate component called Android System WebView. It is essentially an Android system app that comes pre-installed with Android devices. It is periodically updated, just like other system apps such as Google Play Services and the Play Store app. You can see it in your list of installed system apps:
Android 7.0的更改:
从Android N开始,Chrome应用将用于渲染第三方Android应用中的任何/所有WebView
.在开箱即用的Android N手机中,根本没有Android WebView System应用程序.在已收到Android N的OTA更新的设备中,Android系统WebView被禁用:
Starting with Android N, the Chrome app will be used to render any/all WebView
s in third-party Android apps. In phones that have Android N out-of-the-box, the Android WebView System app is not present at all. In devices that have received an OTA update to Android N, the Android System WebView is disabled:
和
此外,已引入多语言环境支持,并且设备具有多种默认语言:
Moreover, multi-locale support has been introduced, with devices having more than one default language:
这对于具有多种语言的应用程序具有重要的意义.如果您的应用包含WebView
,则这些内容将使用Chrome应用呈现.由于Chrome本身就是一个Android应用 ,并以其自己的沙盒流程运行,因此它不会绑定到您的应用设置的语言环境.取而代之的是,Chrome会还原为主要设备的语言环境.例如,假设您的应用语言环境设置为ar-AE
,而设备的主要语言环境是en-US
.在这种情况下,包含WebView
的Activity
的语言环境将从ar-AE
变为en-US
,并且将显示来自相应语言环境文件夹的字符串和资源.您可能会在具有WebView
的Activity
上看到LTR和RTL字符串/资源杂乱无章的内容.
This has an important consequence for apps that have multiple languages. If your app has WebView
s, then those are rendered using the Chrome app. Because Chrome is an Android app in itself, running in its own sandboxed process, it will not be bound to the locale set by your app. Instead, Chrome will revert to the primary device locale. For example, say your app locale is set to ar-AE
, while the primary locale of the device is en-US
. In this case, the locale of the Activity
containing a WebView
will change from ar-AE
to en-US
, and strings and resources from the corresponding locale folders will be displayed. You may see a mish-mash of LTR and RTL strings/resources on those Activity
s that have WebView
s.
解决方案:
此问题的完整解决方案包括两个步骤:
The complete solution to this problem consists of two steps:
步骤1:
首先,在每个Activity
或至少每个具有WebView
的Activity
中手动重置默认语言环境.
First, reset the default locale manually in every Activity
, or at least every Activity
that has a WebView
.
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
参数应该是您想要设置的默认Locale
.例如,如果您希望将阿拉伯语/阿拉伯联合酋长国设置为默认语言环境,则应传递new Locale("ar", "AE")
.或者,如果您希望设置默认语言环境(即操作系统自动设置的Locale
),则应传递Locale.US
.
Call the above method before calling setContentView(...)
in the onCreate()
method of all your Activities. The locale
parameter should be the default Locale
that you wish to set. For example, if you wish to set Arabic/UAE as the default locale, you should pass new Locale("ar", "AE")
. Or if you wish to set the default locale (i.e. the Locale
that is automatically set by the operating system), you should pass Locale.US
.
步骤2:
此外,您需要添加以下代码行:
Additionally, you need to add the following line of code:
new WebView(this).destroy();
Application
类的onCreate()
中的
(如果有的话),以及用户可能在其他任何地方更改语言.这将照顾到在更改语言后重新启动应用程序时可能发生的各种极端情况(您可能已经注意到其他语言的字符串或在Activities
上更改了在Android上具有WebView
的语言后具有相反的对齐方式) 7.0 ++).
in the onCreate()
of your Application
class (if you have one), and wherever else the user may be changing the language. This will take care of all kinds of edge cases that may occur on app restart after changing the language (you may have noticed strings in other languages or with the opposite alignment after changing the language on Activities
that have WebView
s on Android 7.0++).
作为附录, Chrome自定义标签现在是在-应用网页.
As an addendum, Chrome custom tabs are now the preferred way of rendering in-app web pages.
参考:
1.. Android 7.0-WebView
的更改.
2.. 了解WebView和Android安全补丁程序 .
3.. Android版WebView .
5.. 牛轧糖WebView .
6.. Android 7.0牛轧糖 .
7.. Android N之谜,第1部分: Android System WebView只是现在的"Chrome"? .
这篇关于Android-WebView语言在Android 7.0及更高版本上突然改变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!