3 回答
TA贡献1856条经验 获得超17个赞
背景:
Android WebView是使用WebKit构建的。虽然它最初是AOSP的一部分,但从KitKat开始,便决定将其WebView拆分为一个名为Android System WebView的单独组件。本质上,它是一个预装有Android设备的Android系统应用。就像其他系统应用(例如Google Play服务和Play商店应用)一样,它会定期更新。您可以在已安装的系统应用程序列表中看到它:
Android系统WebView
Android 7.0的变化:
从Android N开始,Chrome应用将用于渲染WebView第三方Android应用中的任何/全部。在开箱即用的Android N手机中,根本没有Android WebView System应用程序。在已收到Android N的OTA更新的设备中,Android系统WebView被禁用:
WebView已禁用
和
WebView已禁用
此外,已引入多语言环境支持,并且设备具有多种默认语言:
在此处输入图片说明
对于具有多种语言的应用程序,这具有重要的意义。如果您的应用包含WebView,则这些内容将使用Chrome应用呈现。由于Chrome 本身就是一个Android应用,因此以其自己的沙盒流程运行,因此不会绑定到您的应用设置的语言环境。取而代之的是,Chrome将还原为主要设备的语言环境。例如,假设您的应用语言环境设置为ar-AE,而设备的主要语言环境设置为en-US。在这种情况下,Activity包含的语言环境WebView将从ar-AE变为en-US,并且将显示来自相应语言环境文件夹的字符串和资源。您可能会在Activity具有WebViews的那些s 上看到大量的LTR和RTL字符串/资源。
解决方案:
完整的解决方案包括两个步骤:
步骤1:
首先,在每个Activity(或至少每个Activity具有的)中手动重置默认语言环境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());
}
在调用之前调用上面的方法setContentView(...)在onCreate()所有的活动的方法。该locale参数应该是Locale您希望设置的默认值。例如,如果您希望将阿拉伯语/阿拉伯联合酋长国设置为默认语言环境,则应传递new Locale("ar", "AE")。或者,如果您希望设置默认语言环境(即Locale由操作系统自动设置的语言环境),则应通过Locale.US。
第2步:
此外,您需要添加以下代码行:
new WebView(this).destroy();
在onCreate()您的Application类(如果有的话),和任何其他地方的用户可以更改语言。这将处理在更改语言后重新启动应用程序时可能发生的各种极端情况(您可能已经注意到其他语言的字符串,或者在更改语言后在Android 7.0 ++ 上Activities具有相反的对齐方式WebView)。
作为附录,Chrome自定义标签现在是呈现应用内网页的首选方式。
TA贡献1808条经验 获得超4个赞
您的代码似乎正在为应用本身(MyApplication.getInstance())的配置中设置语言环境。但是,您需要在扩展活动的内容视图之前更新活动上下文的配置。我发现修改应用程序的上下文是不够的(事实证明,甚至没有必要)。如果我不更新每个活动上下文,则行为在各个活动之间是不一致的。
我采用的方法是子类化AppCompatActivity(或者Activity,如果不使用兼容性库,则使用子类化),然后从该子类派生我的所有活动类。这是我的代码的简化版本:
public class LocaleSensitiveActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
Locale locale = ... // the locale to use for this activity
fixupLocale(this, locale);
super.onCreate(savedInstanceState);
...
}
static void fixupLocale(Context ctx, Locale newLocale) {
final Resources res = ctx.getResources();
final Configuration config = res.getConfiguration();
final Locale curLocale = getLocale(config);
if (!curLocale.equals(newLocale)) {
Locale.setDefault(newLocale);
final Configuration conf = new Configuration(config);
conf.setLocale(newLocale);
res.updateConfiguration(conf, res.getDisplayMetrics());
}
}
private static Locale getLocale(Configuration config) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return config.getLocales().get(0);
} else {
//noinspection deprecation
return config.locale;
}
}
}
然后,在调用使用上下文的任何方法(例如)之前,请确保先调用super.onCreate(savedInstanceState)每个子类的onCreate()方法。setContentView()
- 3 回答
- 0 关注
- 1184 浏览
添加回答
举报